Migracja do .NET Standard 2.1

Przenieś istniejącą aplikację Doconut.NETStandard z wersji 26.7.0 do 26.8.0

Doconut ma dwie odrębne integracje .NET Standard. Używają tej samej nazwy pakietu Doconut.NETStandard, więc należy określić generację na podstawie wersji i API w aplikacji przed zmianą pakietów, uruchomieniem, licencjami lub zasobami przeglądarki.

Wersja jest rozdrożeniem

WersjaDocelowaAPI
26.7.0 i niższenetstandard2.0poprzednie API
26.8.0 i wyższenetstandard2.1obecne API

Zwiększenie numeru wersji jest aktualizacją. Nie ma osobnego pakietu do zainstalowania ani warstwy kompatybilności — 26.8.0 ma inną powierzchnię API. Oczekuj błędów kompilacji po podniesieniu wersji; reszta tego przewodnika to ich lista.

Którą integrację używasz?

Jeżeli projekt zawiera…Generacja
new Viewer(_cache, _accessor, ...)Poprzednia
viewer.OpenDocument(...) (synchroniczna)Poprzednia
viewer.InitCache()Poprzednia
UseDoconut(new DoconutOptions { ... })Poprzednia
UseDoconutWebFarm(...) / WebFarmOptionsPoprzednia
Viewer.DoconutLicense(...) lub Viewer.SetLicensePlugin(...)Poprzednia
viewer.Converter.GetConverter()Poprzednia
using Doconut.Configs; / using Doconut.Models;Poprzednia
Ręcznie skopiowane docViewer.js, documentLinks.js, lub docViewer.UI.jsPoprzednia
builder.Services.AddDoconut(...)Obecna
app.UseDoconutResources() plus app.UseDoconut() bez argumentówObecna
Viewer dostarczany przez wstrzykiwanie zależnościObecna
await viewer.OpenDocumentAsync(...)Obecna

Jeśli obie kolumny pojawiają się w tej samej aplikacji, traktuj migrację jako niekompletną. Nie wysyłaj jednego tokenu dokumentu przez zasoby lub middleware z innej generacji.

Najpierw sprawdź framework hosta

To jest twarda bariera, a nie preferencja. Obecny pakiet celuje w netstandard2.1:

HostCzy może używać 26.8.0
.NET Core 3.0 lub nowszy (w tym .NET 5/6/7/8)Tak
.NET Framework, dowolna wersjaNie

.NET Framework nie może odwoływać się do biblioteki netstandard2.1. Jeśli aplikacja działa na .NET Framework, zatrzymaj się tutaj i użyj pakietu Doconut.NETFramework zamiast; od wersji 26.9.0 wymaga .NET Framework 4.7.2. Obie aplikacje referencyjne dla tego wydania celują w net8.0.

Przed migracją

  1. Utwórz gałąź i wdrażalną kopię zapasową istniejącej aplikacji.
  2. Zanotuj dokładne wersje pakietów core i plugin.
  3. Spisz wszystkie wywołania new Viewer(...), wywołania InitCache(), wywołania ładowania licencji, mapowanie UseDoconutWebFarm, kontroler konwersji, skopiowany skrypt Doconut, niestandardową akcję paska narzędzi, wywołanie zwrotne viewer oraz punkt końcowy otwierania dokumentu.
  4. Zachowaj bieżące pliki .lic i sekrety wdrożeniowe poza kontrolą wersji.
  5. Zbierz reprezentatywny zestaw dokumentów PDF, Office, obrazów, CAD, e‑mail, DICOM, przeszukiwalnych, chronionych hasłem i anotowanych.
  6. Zanotuj istniejące ustawienia limitu czasu sesji, zachowanie bezpieczeństwa, czcionki i ustawienia platformy.

Migruj jedno środowisko przed zmianą produkcji. Obecna integracja zmienia czas życia usług, routowanie żądań, własność sesji, dostarczanie zasobów klienta oraz — jeśli prowadzisz farmę — sposób, w jaki strony docierają do przeglądarki.

1. Przestrzenie nazw: prawie wszystko przeniesiono do korzenia

Typy konfiguracyjne były rozproszone w czterech przestrzeniach nazw. Teraz wszystkie znajdują się w Doconut.

WcześniejTeraz
using Doconut.Configs.View;using Doconut;
using Doconut.Models;using Doconut;
using Doconut.Configs;using Doconut;
using Doconut.Configs.Cloud;using Doconut.Clouds;
using Doconut.Configs.Conversion;bez zmian
using Doconut.Middleware;bez zmian

Nazwy typów nie uległy zmianie: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, CloudUploadConfig, AzureConfig, CDNConfig, FileShareConfig i reszta nadal istnieje. W większości plików cała edycja polega na usunięciu dwóch linii using.

Doconut.Configs.Editor (BaseConfigEditor, PdfConfigEditor) został usunięty i nie ma zamiennika w tym pakiecie. Jeśli Twoja aplikacja odwoływała się do tych typów, zaplanuj tę część osobno i nie traktuj jej jako części tej migracji.

2. Kompatybilność pakietu i licencji

Zamień lub zaktualizuj pakiet podstawowy celowo; nie polegaj na identycznym identyfikatorze pakietu, aby wybrać nowe API. Domyślne polecenie instaluję najnowsze stabilne wydanie:

bash
dotnet add package Doconut.NETStandard

Aby uzyskać odtwarzalną migrację do wydania audytowanego w tym przewodniku, przekaż wersję jako oddzielną opcję:

bash
dotnet add package Doconut.NETStandard --version 26.8.0

Utrzymuj każdy wtyczkę Doconut w tej samej wersji co pakiet podstawowy — Doconut.NETStandard.Converter i Doconut.NETStandard.Dicom. Obecna integracja ładuje licencje raz podczas AddDoconut(), używając następującego priorytetu:

text
LicenseStream > LicenseContent > LicensePath > automatic discovery

Automatyczne wykrywanie szuka Doconut.Viewer.lic oraz plików towarzyszących Doconut.Viewer.<Capability>.lic. Poprzednie wywołania statyczne Viewer.DoconutLicense(...) i Viewer.SetLicensePlugin(...) nie są już mechanizmem uruchamiania, podobnie jak List<string> ścieżek licencji, które akceptował stary konstruktor Viewer. Przenieś licencję do DoconutOptions, trzymaj pliki towarzyszące razem przy użyciu automatycznego wykrywania, uruchom ponownie po zmianie licencji i zweryfikuj możliwości przez IDoconutLicenseService.

Nie zakładaj, że obecność starej licencji wtyczki dowodzi uprawnienia do bieżącej kompilacji wtyczki. Testuj osobno Viewer, Search, Annotation, Converter i DICOM przy użyciu zatwierdzonych artefaktów wydania.

3. Uruchamianie i wstrzykiwanie zależności

Wcześniej przeglądarka była tworzona na żądanie, a opcje przekazywane do pośrednika:

csharp
// Poprzednia integracja — tylko kontrast; nie kompiluj tego z bieżącym SDK.
var viewer = new Viewer(_cache, _accessor);
// …
appBranch.UseDoconut(new DoconutOptions { UnSafeMode = false, ShowDoconutInfo = false });

Obecna integracja rejestruje Doconut raz i otrzymuje Viewer z wstrzykiwania zależności:

csharp
builder.Services.AddDoconut(options =>
{
    options.UnsafeMode      = false;   // uwaga na zmianę pisowni: UnSafeMode → UnsafeMode
    options.ShowDoconutInfo = false;
    options.LicensePath     = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // stan sesji wymaga pamięci podręcznej (MVC/Razor Pages już dodają jedną)
builder.Services.AddSession();

app.UseSession();
app.UseDoconutResources();
app.UseDoconut();

Viewer jest usługą przejściową. Menedżer sesji dokumentu i jego pamięć podręczna posiadają długotrwały stan dokumentu, a nie konkretną wstrzykniętą instancję Viewer.

Trzy rzeczy do przeniesienia:

  • new Viewer(cache, accessor) został usunięty. Wstrzyknij Doconut.Viewer do swojego kontrolera lub użyj @inject Doconut.Viewer Viewer w widoku Razor.
  • UseDoconutResources() zastępuje ręczne wiązanie app.UseMiddleware<EmbeddedResourceMiddleware>() i musi być uruchomione przed gałęzią dokumentu.
  • UnSafeMode → UnsafeMode. Jednoznakowa zmiana nazwy, którą wykryje kompilator.

Kiedy UnsafeMode jest false, SDK weryfikuje token sesji względem pierwotnego żądania, więc AddSession() / UseSession() muszą nadal znajdować się w potoku, UseSession() przed gałęzią.

Metody, które już nie istnieją

PrzedTeraz
viewer.OpenDocument(path, config, options)await viewer.OpenDocumentAsync(path, config, options)
viewer.InitCache()usunięto — nie ma nic do ręcznego podgrzewania; usuń wywołanie i wszelkie flagi „czy już zainicjowałem?” wokół niego
viewer.ExportToPng(sharedPath)zobacz §7
viewer.ExportToCloud(cloudConfig)zobacz §7
using var v = new Viewer(...); v.CloseDocument(t)viewer.CloseDocument(token) na wstrzykniętej instancji

4. Środkowe oprogramowanie i routowanie zasobów

UseDoconut() teraz nie przyjmuje żadnych argumentów. Kształt gałęzi MapWhen nie musi się zmieniać — tylko pośrednik wewnątrz niej:

csharp
app.UseDoconutResources();   // PRZED gałęzią

app.MapWhen(
    ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
    branch => branch.UseDoconut());

W bieżącym potoku:

  1. wywołaj UseSession() przed Doconut, gdy zabezpieczenia sesji są włączone;
  2. wywołaj UseDoconutResources() przed UseDoconut();
  3. utrzymaj ResourcesPath, wygenerowane adresy URL zasobów i klienta ResPath w zgodzie;
  4. utrzymaj mapowaną gałąź i klienta BasePath w zgodzie.

MiddlewarePath jest zweryfikowaną konfiguracją; nie tworzy ona samodzielnie gałęzi ASP.NET Core.

5. Budowa i czas życia przeglądarki

Usuń pamięci podręczne własności aplikacji przechowujące obiekty Viewer. Nie pozostaje nic w Viewer warto zachować: nie zawiera żadnego stanu dokumentu, a pamięć podręczna sesji posiada wszystko co przetrwa żądanie. Wstrzyknij go do punktu końcowego, strony Razor, kontrolera lub scoped usługi aplikacji:

csharp
app.MapPost("/api/open", async (Viewer viewer) =>
{
    var token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
    return Results.Ok(new { token });
});

Zwrócony token identyfikuje sesję dokumentu po stronie serwera. Traktuj go jako poświadczenie nośnika poświadczenie: nie loguj go, nie przechowuj ani nie umieszczaj w analizach.

6. Otwieranie i zamykanie dokumentów

Zastąp synchroniczny OpenDocument(...) przez OpenDocumentAsync(...):

csharp
// Aktualna integracja: Viewer pochodzi z DI i otwieranie dokumentu jest asynchroniczne.
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });

Obecne przeciążenia akceptują ścieżkę pliku lub strumień, opcjonalną konfigurację formatu, opcjonalny DocOptions oraz token anulowania. Zamknij sesję serwera explicite, gdy przeglądarka już go nie potrzebuje:

csharp
viewer.CloseDocument(token);

Usuń każde wywołanie InitCache() oraz flagę go chroniącą — nie ma nic do ręcznego podgrzewania ręcznie. Nie używaj ponownie tokenu wygenerowanego przez poprzednią bibliotekę po przejściu: otwórz każdy dokument ponownie za pomocą bieżącego API.

7. Web farm → rozproszony: największa zmiana

UseDoconutWebFarm i WebFarmOptions nie istnieją już. Jeśli twoja aplikacja wywołuje je, ta sekcja jest twoją aktualizacją; jeśli nie, przejdź do §8.

Wcześniej jedno pośrednictwo robiło wszystko: serwowało wstępnie wyrenderowane obrazy z udostępnionego folderu i odpytywało, gdy inny węzeł nadal je zapisywał.

csharp
// Poprzednia integracja — jedno wywołanie, niejawna koordynacja przez system plików.
appBranch.UseDoconutWebFarm(new WebFarmOptions
{
    Path                = Path.Combine(env.WebRootPath, "webfarm"),
    PageWaitTimeSeconds = 180,
    StartWaitFromPage   = 5,
});

To samo zadanie jest teraz podzielone na dwie wyraźne połówki. Strona zapisu — węzeł, który otwiera dokument, publikuje cały zestaw artefaktów (strony, informacje o dokumencie, indeks wyszukiwania, metadane) w udostępnionym miejscu:

csharp
var result = await _publisher.PublishAsync(          // DistributedDocumentPublisher, wstrzyknięty z DI
    pathToFile,
    new FileShareConfig
    {
        Location              = CloudLocation.FileShare,
        RootPath              = @"\\fileserver\doconut",   // ten sam folder, którego używasz dzisiaj
        UsePerTokenSubfolders = true,
    },
    config,
    documentOptions,
    new DistributedDocumentPublishOptions
    {
        CleanUpStagingDirectory = true,
        FirstPagePriority       = true,
    });

return Content(result.Token);

Strona odczytu — każdy węzeł serwuje z udostępnionego miejsca:

csharp
app.MapWhen(
    ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
    branch => branch.UseDoconutCloud<FileShareCloudHandler>(options =>
    {
        options.Location          = CloudLocation.FileShare;
        options.CloudUploadConfig = /* ten SAME FileShareConfig jak powyżej */;
    }, "/"));
PrzedTeraz
WebFarmOptions.PathFileShareConfig.RootPath
PageWaitTimeSeconds / StartWaitFromPageusunięto — zastąpiono FirstPagePriority po stronie zapisu oraz FileShareConfig.ReadReadyPollMs po stronie odczytu
viewer.OpenDocument(...) następnie viewer.ExportToPng(share)jedno wywołanie PublishAsync(...)
DocOptions.IsWebfarm / WebfarmPathwciąż tam, zapisane jako IsWebFarm / WebFarmPath — ale nie potrzebne w ścieżce publikacji

Twoja topologia nie zmienia się. Wskaż RootPath na ten sam udział UNC i każdy węzeł działa tak, jak działa dzisiaj. Zmiana polega na tym, że publikowanie jest operacją, którą wywołujesz, zamiast skutku ubocznego renderowania.

Obie połówki muszą się zgadzać. Jeśli RootPath lub UsePerTokenSubfolders różnią się między wydawcą a obsługującym, drugi węzeł zwróci 404. Zbuduj konfigurację w jednym pomocniku i wywołaj ją z obu stron.

PageWaitTimeSeconds = 180 oznaczało „zablokuj do trzech minut, mając nadzieję, że strona się pojawi”. Zastąpienie jest wyraźne: z FirstPagePriority = true, strona 1 jest dostępna od razu a późniejsze strony odpowiadają HTTP 202 Accepted, dopóki nie zostaną zapisane. Wbudowana przeglądarka ponawia automatycznie, gdy retryOn409 jest ustawione. Klient, który nie ponawia, pokaże uszkodzone kafelki dla stron nadal renderowanych.

Pełna konfiguracja, w tym publikowanie w tle i bilety dostępu, znajduje się w Rozproszone wdrożenia.

8. Konwersja jest wtyczką i znacznie mniejsza

Zarejestruj wtyczkę, a następnie wstrzyknij fasadę DocumentConverter:

csharp
builder.Services.AddDoconut(o => o.AddPlugin<ConverterPlugin>());
csharp
// Poprzednia integracja
var converter = viewer.Converter.GetConverter();
var config    = new WordConfigConverter { TargetFormat = WordConfigConverter.EnTargetFormat.PDF };
var result    = converter.Convert(stream, SourceFormatConverter.DOCX, config);

// Bieżąca integracja
var result = await _converter.ConvertAsync(stream, ".docx", ConversionTarget.Pdf, null, ct);

Co to zastępuje:

  • SourceFormatConverter — usunięto. Przekaż rozszerzenie pliku jako ciąg znaków, z kropką.
  • Typy *ConfigConverter dla każdej rodziny (WordConfigConverter, ExcelConfigConverter, …), każdy z zagnieżdżonym wyliczeniem EnTargetFormat — usunięto. Teraz istnieje jedno wyliczenie ConversionTarget dla każdej rodziny.
  • viewer.Converter.GetConverter() — usunięto. Wstrzyknij Doconut.DocumentConverter.

ConvertAsync zwraca strumień z możliwością przewijania, więc return File(result, mime, name) działa bezpośrednio — kopiowanie starego kodu MemoryStream nie jest potrzebne. W dostarczonym przykładzie usunięto przełącznik rozszerzeń z 68 przypadkami oraz dziesięć prawie identycznych kontrolerów.

Zobacz Wtyczka konwertera dla pełnego zakresu.

9. Dostawcy chmury

UseDoconutCloud stał się generyczny. Dostawca jest argumentem typu zamiast wartości Location przełączanej wewnątrz middleware:

csharp
// Poprzednia integracja
appBranch.UseDoconutCloud(new CloudOptions { Location = CloudLocation.CDN, ... });

// Bieżąca integracja
branch.UseDoconutCloud<CDNCloudHandler>(options =>
{
    options.Location          = CloudLocation.CDN;
    options.CloudUploadConfig = new CDNConfig { DoconutCdnUrl = "..." };
}, "/");

Klasy konfiguracyjne są niezmienione, poza przestrzenią nazw (Doconut.Configs.Cloud → Doconut.Clouds): AzureConfig, AmazonConfig, GoogleCloudConfig, DropBoxConfig, RedisConfig, CDNConfig, FTPConfig, plus nowy FileShareConfig. Obsługujące są nazwane <Provider>CloudHandler.

Obsługa CDN jest tylko do odczytu — serwuje to, co już znajduje się w CDN; nie dokonuje przesyłania.

10. Obiekty konfiguracyjne, które zmieniły nazwę

PoprzednioTeraz
DoconutOptions.UnSafeModeUnsafeMode
DocOptions.IsWebfarmIsWebFarm
DocOptions.WebfarmPathWebFarmPath
DocOptions.ImageResolutionwciąż obecny, ale przestarzały — ustaw rozdzielczość w konfiguracji formatu zamiast tego

DocOptions również zyskuje IsSecured.

Obecne API również rozdziela zagadnienia bardziej rygorystycznie niż poprzednie, więc sprawdź, czy każde ustawienie znajduje się w obiekcie, który teraz je posiada:

ZagadnienieObecny typ
Ścieżki middleware, licencjonowanie, rejestracja wtyczkiDoconutOptions
Hasło, limit czasu, bezpieczeństwo, znak wodnyDocOptions
Renderowanie formatu i DPIPdfConfig, WordConfig, ExcelConfig, i inne typy BaseConfig
Domyślne ustawienia widgetu przeglądarkiViewerConfig lub równoważne opcje JavaScript
Wygenerowane CSS i skryptyCssConfig i ScriptConfig
Współdzielona pamięć i dostawcy chmuryFileShareConfig i inne konfiguracje Doconut.Clouds

Nie przenoś DocOptions.ImageResolution dalej jako kontrolki renderowania. Jest przestarzały; ustaw BaseConfig.ImageResolution w konfiguracji specyficznej dla formatu. Przejrzyj wszystkie domyślne ustawienia zamiast zakładać, że poprzednia konfiguracja zachowuje się tak samo.

11. Przeglądarka po stronie klienta — dwie zmiany, które zawodzą PO CICHU

Obie te zmiany pozostawiają serwer w pełni sprawnym. Twój dokument jest renderowany, strona wygląda poprawnie i nic nie pojawia się w konsoli przeglądarki. Przeczytaj tę sekcję, nawet jeśli Twój C# kompiluje się za pierwszym razem.

Wywołania zwrotne przeglądarki są teraz opcjami, a nie funkcjami globalnymi

Poprzednia przeglądarka wywoływała Twoje obsługi według nazwy, wyprowadzając nazwę funkcji globalnej z identyfikatora kontenera. Deklarowanie function ctlDoc_OnViewerReady() na stronie z <div id="div_ctlDoc"> było wystarczające. Obecna przeglądarka przyjmuje wyraźne wywołania zwrotne w obiekcie opcji i nie szuka już tych globalnych funkcji:

javascript
objctlDoc = $("#div_ctlDoc").docViewer({
    // ... twoje istniejące opcje ...
    onViewerBusy:     ctlDoc_OnViewerBusy,      // zostało znalezione po nazwie
    onViewerReady:    ctlDoc_OnViewerReady,     // zostało znalezione po nazwie
    onCopy:           ctlDoc_Copy,              // było ctlDoc_Copy(text)
    onAutoLoadStatus: ctlDoc_AutoLoadStatus     // było ctlDoc_AutoLoadStatus(page)
});

Dlaczego to jest nieprzyjemne: stare wywołanie było opakowane w pusty catch, który pochłaniał wszystko. Teraz Twoje funkcje po prostu nigdy się nie uruchamiają i nic nie zgłasza błędu. Typowy objaw to nieustannie obracający się wskaźnik — ponieważ funkcja, która go ukrywała, była ctlDoc_OnViewerReady. Dokument za nim jest w porządku.

Pełna lista opcji to onPageLoading, onPageLoaded, onThumbnailClicked, onPageClicked, onDoubleClick, onViewerBusy, onViewerReady, onViewerError, onCopy, onAnnSaved, onAnnSaveError, onAnnLoaded, onAnnClosed, onAutoLoadStatus, onThumbsShown i onError. Nie ma wywołania zwrotnego przy kliknięciu linku: obsługa hiperłączy jest wbudowana, sterowana przez showHyperlinks.

ResPath musi wskazywać na prefiks zasobu

javascript
ResPath: '',                      // WCZEJŚNIEJ — zasoby pochodziły z katalogu głównego aplikacji
ResPath: 'doconut-res/images',    // TERAZ    — prefiks UseDoconutResources() montuje

Jeśli zmieniłeś prefiks za pomocą DoconutOptions.ResourcesPath, użyj tej wartości zamiast tego.

12. Pasek narzędzi przeglądarki, wyszukiwanie i adnotacje

Nie migruj starych skryptów pojedynczo. Obecne aplikacje referencyjne tworzą jeden kompletny pakiet strony:

  1. wyemituj CSS przeglądarki i licencjonowany CSS wyszukiwania/adnotacji przy użyciu ReferenceCss;
  2. renderuj pasek narzędzi przeglądarki należący do aplikacji;
  3. renderuj searchBarMount, annBarMount i wymagane zamontowanie przeglądarki;
  4. wyemituj skrypty przeglądarki i licencjonowane moduły przy użyciu ReferenceScripts;
  5. załaduj własny skrypt pomocniczy paska narzędzi aplikacji;
  6. zainicjalizuj jeden objViewer;
  7. zainicjalizuj licencjonowane wstążki wyszukiwania i adnotacji;
  8. wywołaj attach(objViewer) na każdej wstążce;
  9. otwórz dokument i wywołaj objViewer.View(token).

Wyszukiwanie i adnotacje są modułami podłączonymi do tej samej przeglądarki, a nie niezależnymi paskami narzędzi. Główny pasek narzędzi należy do aplikacji hosta; wstążki wyszukiwania i adnotacji są osadzone, zasoby z ograniczeniami funkcjonalności.

Usuń ręcznie skopiowane pliki, takie jak documentLinks.js i docViewer.UI.js, dopiero po tym, jak bieżąca strona będzie działać z zasobami wyemitowanymi przez ReferenceCss i ReferenceScripts.

13. Rejestracja wtyczek

Statyczne metody licencji wtyczek nie rejestrują bieżących wtyczek. Zainstaluj i zarejestruj każdy wydany pakiet explicite:

csharp
builder.Services.AddDoconut(options =>
{
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
    options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});

AddDoconut() waliduje zarejestrowane możliwości wtyczek przy uruchamianiu. Converter i DICOM są wydanymi wtyczkami .NET Standard. Normalne wyszukiwanie i adnotacje są wbudowanymi licencjonowanymi funkcjami, a nie pakietami AddPlugin<TPlugin>().

14. Sesja i bezpieczeństwo dokumentu

Obecna integracja wiąże dokumenty z nieprzezroczystymi tokenami i buforowanymi sesjami. Z domyślnym UnsafeMode = false, UseDoconut() dodaje bezpieczeństwo dostępu do dokumentu i host musi skonfigurować sesję ASP.NET:

csharp
builder.Services.AddDistributedMemoryCache(); // stan sesji wymaga pamięci podręcznej (MVC/Razor Pages już dodają jedną)
builder.Services.AddSession();
app.UseSession();

Zachowaj DocOptions.IsSecured = true, chyba że przeglądany projekt wymaga inaczej. Nigdy nie używaj UnsafeMode = true jako skrótu migracji na pojedynczym węźle. Testuj żądania bez tokena, z uszkodzonym tokenem, z wygasłym tokenem oraz z tokenem z innej sesji przeglądarki.

W farmie żądanie strony może trafić na węzeł, który nigdy nie widział żądania otwierającego, więc sprawdzenie per-sesja odrzuci je. To jedyny przypadek, w którym UnsafeMode = true jest prawidłowy — i musi być połączony z podpisanymi biletami dostępu przez AddDoconutDistributedDocumentSecurity, a nie dostarczany samodzielnie. Zobacz Rozproszone wdrożenia.

Uwaga dotycząca nazewnictwa

We wszystkich frameworkach klasa to Viewer. Jeśli znajdziesz DocumentViewer w starych fragmentach kodu lub artykułach firm trzecich, ten typ nigdy nie istniał w SDK.

15. Sugerowana kolejność prac

  1. Potwierdź, że framework hosta może konsumować netstandard2.1. Jeśli nie, zatrzymaj się.
  2. Zaktualizuj pakiet do 26.8.0 i zbuduj. Przejdź przez błędy kompilacji — większość to linie using w §1.
  3. Przenieś uruchamianie do AddDoconut() i wywołania middleware do ich nowej kolejności (§3, §4).
  4. Wstrzyknij Viewer tam, gdzie go konstruowałeś, uczynij OpenDocument asynchronicznym i usuń InitCache() (§5, §6).
  5. Jeśli używasz farmy webowej, wykonaj §7 — jedyną część, która jest przeprojektowaniem, a nie zmianą nazwy.
  6. Jeśli konwertujesz dokumenty, wykonaj §8.
  7. Wykonaj §11 — zmiany po stronie klienta. To one, które nie ogłoszą się same.
  8. Otwórz prawdziwy dokument w przeglądarce i obserwuj kręcący się wskaźnik. Zielona kompilacja nie dowodzi niczego: licencjonowanie, rejestracja wtyczek, ścieżka zasobu i wywołania zwrotne przeglądarki zawodzą dopiero w czasie wykonywania. Dla farmy, zweryfikuj, że dokument opublikowany przez jeden węzeł jest serwowany przez inny.

Testowanie migracji

W minimalnym zakresie, zweryfikuj:

  • uruchomienie aplikacji z licencją produkcyjną i wszystkimi zarejestrowanymi wtyczkami;
  • CSS/skrypty przeglądarki i wszystkie żądania obrazów stron w wybranych ścieżkach;
  • otwieranie dokumentu, nawigację, przybliżanie, miniatury, drukowanie oraz wyraźne zamknięcie;
  • wyszukiwanie w dokumencie zawierającym tekst oraz stan nie‑wyszukiwalności pliku zawierającego wyłącznie obrazy;
  • ładowanie, zapisywanie, eksport adnotacji oraz kontrola możliwości;
  • wykrywanie docelowego konwertera, wyjście, pobieranie i stan znaku wodnego;
  • strony DICOM, klatki i animacje; metadane techniczne nie są dostępne w tym pakiecie;
  • dokumenty chronione hasłem, niestandardowe czcionki, tekst niełaciński oraz skonfigurowane limity czasu;
  • odrzucanie tokenów między sesjami oraz zachowanie przy wygasłej sesji;
  • w przypadku farmy: publikacja na jednym węźle, żądanie późniejszej strony z innego i potwierdzenie, że przeglądarka ponawia 202 odpowiedzi zamiast wyświetlać uszkodzone kafelki;
  • tryb mobilny, tryb ciemny oraz ścieżka odwróconego proxy produkcji.

Plan przywracania

Zachowaj poprzedni artefakt wdrożeniowy, pasujące pakiety, pliki licencji oraz skopiowane zasoby przeglądarki razem. Bezpieczne przywrócenie przełącza całą generację aplikacji; nie miesza serwera poprzedniej generacji z bieżącymi skryptami ani bieżącego serwera z new Viewer(...) miejscami wywołań.

Przed przełączeniem, udokumentuj:

  • slot wdrożeniowy lub artefakt używany do przywracania;
  • wpływ współdzielonego magazynu, jeśli istnieje — artefakty opublikowane przez 26.8.0 nie są konsumowane przez poprzednie oprogramowanie pośredniczące farmy webowej;
  • sposób unieważniania aktywnych sesji dokumentów;
  • kontrola zdrowia i dokument testowy używany do podjęcia decyzji o przywróceniu;
  • kto może przywrócić poprzedni zestaw pakietów i konfigurację.

Dokumentacja starsza

Przetłumana poprzednia instrukcja pozostaje dostępna pod adresem Starsza konfiguracja .NET Standard. Poprzednia brama integracyjna wyjaśnia te same sygnały identyfikacyjne i odsyła z powrotem do tego przewodnika migracji.

Zachowaj historyczny adres URL w zakładkach i zgłoszeniach wsparcia, dopóki instalacje netstandard2.0 nadal istnieją. Dokumentuje on inną generację i nie jest przekierowywany do bieżącego API.

Czy ta strona była pomocna?