Migracja do .NET Standard 2.1

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

Doconut posiada 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, uruchamianiem, licencjami lub zasobami przeglądarki.

Wersja jest rozdrożeniem

Obie generacje publikują się pod tą samą identyfikacją pakietu. Tylko wersja je odróżnia:

WersjaDocelowaAPI
26.7.0 i niżejnetstandard2.0poprzednie API
26.8.0 i wyżejnetstandard2.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. Spodziewaj się błędów kompilacji po podniesieniu wersji; reszta tego przewodnika to ich lista.

Jakiej integracji używasz?

Jeśli projekt zawiera…Generacja
new Viewer(_cache, _accessor, ...)Poprzednia
viewer.OpenDocument(...) (synchronous)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
Manually copied docViewer.js, documentLinks.js, or docViewer.UI.jsPoprzednia
builder.Services.AddDoconut(...)Obecna
app.UseDoconutResources() plus app.UseDoconut() with no argumentsObecna
Viewer supplied by dependency injectionObecna
await viewer.OpenDocumentAsync(...)Obecna

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

Sprawdź najpierw 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 później (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; 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ów.
  3. Sporządź inwentaryzację każdego wywołania new Viewer(...), wywołania InitCache(), wywołania ładowania licencji, mapowania UseDoconutWebFarm, kontrolera konwersji, skopiowanego skryptu Doconut, niestandardowej akcji paska narzędzi, wywołania zwrotnego viewer oraz punktu końcowego otwierania dokumentu.
  4. Zachowaj bieżące pliki .lic oraz sekrety wdrożeniowe poza kontrolą wersji.
  5. Zbierz reprezentatywny zestaw dokumentów PDF, Office, obrazów, CAD, e‑maili, DICOM, przeszukiwalnych, chronionych hasłem i anotowanych.
  6. Zanotuj istniejące ustawienia limitu czasu sesji, zachowania bezpieczeństwa, czcionki i ustawienia platformy.

Migruj jedno środowisko przed zmianą produkcji. Obecna integracja zmienia czas życia usług, routing żą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 po czterech przestrzeniach nazw. Teraz wszystkie znajdują się w Doconut.

PrzedTeraz
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 pozostałe nadal istnieją. 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 elementu tej migracji.

2. Zgodność pakietów i licencji

Zamień lub zaktualizuj pakiet podstawowy świadomie; nie polegaj na identycznym identyfikatorze pakietu, aby wybrać nowe API. Domyślne polecenie instalują najnowszą stabilną wersję:

bash
dotnet add package Doconut.NETStandard

Aby uzyskać powtarzalną 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 plugin Doconut w tej samej wersji co pakiet podstawowy — Doconut.NETStandard.Converter i Doconut.NETStandard.Dicom. Aktualna integracja ładuje licencje raz podczas AddDoconut(), używając następującego priorytetu:

text
LicenseStream > LicenseContent > LicensePath > automatic discovery

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

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

3. Uruchamianie i wstrzykiwanie zależności

Wcześniej viewer był tworzony na żądanie i opcje przekazywane do middleware:

csharp
// Poprzednia integracja — tylko w celach porównawczych; 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: zmiana 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łużej żyjący stan dokumentu, a nie konkretna wstrzyknięta instancja Viewer.

Trzy rzeczy do przeniesienia:

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

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

Metody, które już nie istnieją

PoprzednioTeraz
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. Middleware i routing zasobów

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

csharp
app.UseDoconutResources();   // BEFORE the branch

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 zabezpieczenie sesji jest włączone;
  2. wywołaj UseDoconutResources() przed UseDoconut();
  3. utrzymuj ResourcesPath, generowane adresy URL zasobów oraz ResPath klienta w zgodzie;
  4. utrzymuj mapowaną gałąź i BasePath klienta w zgodzie.

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

5. Budowa i czas życia Viewera

Usuń pamięci podręczne Viewer zarządzane przez aplikację. W Viewer nie ma już nic, co warto byłoby zachować: nie przechowuje on stanu dokumentu, a pamięć podręczna sesji posiada wszystko, co przetrwa żądanie. Wstrzyknij go do punktu końcowego, strony Razor, kontrolera lub usług aplikacji o zasięgu scoped:

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 jak poświadczenie typu bearer: nie loguj go, nie przechowuj i nie umieszczaj w analizach.

6. Otwieranie i zamykanie dokumentów

Zastąp synchroniczne OpenDocument(...) wywołaniem OpenDocumentAsync(...):

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

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

csharp
viewer.CloseDocument(token);

Usuń każde wywołanie InitCache() oraz flagę je chroniącą — nie ma nic, co trzeba by ręcznie podgrzewać. Nie używaj ponownie tokenu utworzonego przez poprzednią bibliotekę po migracji: otwieraj każdy dokument ponownie przez bieżące API.

7. Web farm → rozproszony: największa zmiana

UseDoconutWebFarm i WebFarmOptions nie istnieją już. Jeśli Twoja aplikacja je wywołuje, ten rozdział jest Twoją aktualizacją; jeśli nie, przejdź do §8.

Wcześniej jedno pośredniczące oprogramowanie 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 części. Strona zapisu — węzeł otwierający dokument publikuje cały zestaw artefaktów (strony, informacje o dokumencie, indeks wyszukiwania, metadane) do udziału:

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 dziś
        UsePerTokenSubfolders = true,
    },
    config,
    documentOptions,
    new DistributedDocumentPublishOptions
    {
        CleanUpStagingDirectory = true,
        FirstPagePriority       = true,
    });

return Content(result.Token);

Strona odczytu — dowolny węzeł serwuje z udziału:

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 SAM FileShareConfig jak powyżej */;
    }, "/"));
PrzedTeraz
WebFarmOptions.PathFileShareConfig.RootPath
PageWaitTimeSeconds / StartWaitFromPagezniknęło — zastąpiono FirstPagePriority po stronie zapisu oraz FileShareConfig.ReadReadyPollMs po stronie odczytu
viewer.OpenDocument(...) then viewer.ExportToPng(share)jedno wywołanie PublishAsync(...)
DocOptions.IsWebfarm / WebfarmPathwciąż istnieje, zapisane jako IsWebFarm / WebFarmPath — ale nie jest potrzebne w ścieżce publikacji

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

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

PageWaitTimeSeconds = 180 oznaczało „zablokuj do trzech minut, licząc na pojawienie się strony”. Zastąpienie jest jawne: z FirstPagePriority = true strona 1 jest dostępna od razu, a kolejne strony zwracają HTTP 202 Accepted aż do zapisania. Wbudowany viewer ponawia automatycznie, gdy ustawiono retryOn409. Klient, który nie ponawia, zobaczy uszkodzone kafelki dla wciąż renderowanych stron.

Pełny układ, 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);

// Aktualna 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 do MemoryStream, które było potrzebne w starej wersji, jest niepotrzebne. W dostarczonym przykładzie usunięto przełącznik rozszerzeń z 68 przypadkami oraz dziesięć prawie identycznych kontrolerów.

Zobacz Wtyczka konwertera po pełną funkcjonalność.

9. Dostawcy chmury

UseDoconutCloud stało się generyczne. Dostawca jest argumentem typu zamiast wartości Location wybieranej w środku middleware:

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

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

Klasy konfiguracyjne pozostają niezmienione poza przestrzenią nazw (Doconut.Configs.Cloud → Doconut.Clouds): AzureConfig, AmazonConfig, GoogleCloudConfig, DropBoxConfig, RedisConfig, CDNConfig, FTPConfig, oraz nowy FileShareConfig. Obsługiwacze noszą nazwę <Provider>CloudHandler.

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

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

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

DocOptions zyskuje również IsSecured.

Obecne API jeszcze bardziej rozdziela odpowiedzialności niż poprzednie, więc sprawdź, czy każde ustawienie znajduje się w obiekcie, który teraz je posiada:

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

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

11. Klientowy podgląd — dwie zmiany, które zawodzą PO CZYWIE

Obie te zmiany nie wpływają na działanie serwera. Dokument jest renderowany, strona wygląda poprawnie i w konsoli przeglądarki nie pojawia się nic. Przeczytaj tę sekcję, nawet jeśli Twój kod C# kompiluje się za pierwszym razem.

Wywołania zwrotne podglądu są teraz opcjami, a nie funkcjami globalnymi

Poprzedni podgląd wywoływał Twoje obsługiwacze po nazwie, wyprowadzając nazwę funkcji globalnej z identyfikatora kontenera. Deklaracja function ctlDoc_OnViewerReady() na stronie z <div id="div_ctlDoc"> była wystarczająca. Obecny podgląd przyjmuje wyraźne wywołania zwrotne w obiekcie opcji i już nie szuka tych globalnych funkcji:

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

Dlaczego to jest problematyczne: stare wywołanie było owinięte w pusty catch, który pochłaniał wszystkie błędy. Teraz Twoje funkcje po prostu nie są uruchamiane i nic nie zgłasza błędu. Typowym objawem jest spinner, który nigdy nie przestaje się obracać — ponieważ funkcja, która go ukrywała, to ctlDoc_OnViewerReady. Dokument za nią jest w porządku.

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

ResPath musi wskazywać prefiks zasobu

javascript
ResPath: '',                      // PRZED — zasoby pochodziły z katalogu głównego aplikacji
ResPath: 'doconut-res/images',    // TERAZ — prefiks montowany przez UseDoconutResources()

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

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 oraz licencjonowany CSS wyszukiwania/adnotacji przy użyciu ReferenceCss;
  2. wygeneruj pasek narzędzi przeglądarki należący do aplikacji;
  3. wygeneruj searchBarMount, annBarMount oraz wymagany montaż przeglądarki;
  4. wyemituj skrypty przeglądarki i licencjonowanych modułów przy użyciu ReferenceScripts;
  5. załaduj własny skrypt pomocniczy paska narzędzi aplikacji;
  6. zainicjalizuj jedną instancję 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ą wbudowanymi, ograniczonymi możliwościami zasobami.

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 licencjonowania wtyczek nie rejestrują bieżących wtyczek. Zainstaluj i zarejestruj każdą wydaną paczkę explicite:

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

AddDoconut() weryfikuje 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 nieprzejrzystymi tokenami i buforowanymi sesjami. Przy domyślnym UnsafeMode = false, UseDoconut() dodaje zabezpieczenie 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();

Utrzymuj DocOptions.IsSecured = true, chyba że zweryfikowany projekt wymaga inaczej. Nigdy nie używaj UnsafeMode = true jako skrótu migracji na pojedynczym węźle. Testuj żądania bez tokenu, z nieprawidłowym 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 otwarcia, 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 poprzez AddDoconutDistributedDocumentSecurity, a nie używany 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, taki typ nigdy nie istniał w SDK.

15. Sugerowana kolejność działań

  1. Potwierdź, że framework hosta może konsumować netstandard2.1. Jeśli nie, zatrzymaj się.
  2. Zaktualizuj pakiet do wersji 26.8.0 i zbuduj. Rozwiąż 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 tworzono, uczyn OpenDocument asynchronicznym i usuń InitCache() (§5, §6).
  5. Jeśli używasz farmy webowej, wykonaj §7 — jedyna 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 wskaźnik ładowania. Zielona kompilacja nic tu nie potwierdza: licencjonowanie, rejestracja wtyczek, ścieżka zasobów 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

Co najmniej, zweryfikuj:

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

Plan przywracania

Zachowaj poprzedni artefakt wdrożeniowy, odpowiadają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 miejscami wywołań new Viewer(...).

Przed przełączeniem, udokumentuj:

  • slot wdrożeniowy lub artefakt używany do przywracania;
  • wpływ na współdzielone przechowywanie, jeśli istnieje — artefakty opublikowane przez wersję 26.8.0 nie są konsumowane przez poprzednie oprogramowanie pośredniczące farmy webowej;
  • w jaki sposób aktywne sesje dokumentów zostaną unieważnione;
  • sprawdzanie stanu 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 archiwalna

Poprzedni przetłumaczony podręcznik jest dostępny pod adresem Starsza konfiguracja .NET Standard. Poprzednia brama integracji wyjaśnia te same sygnały identyfikacyjne i odsyła 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?