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:
| Wersja | Docelowa | API |
|---|---|---|
| 26.7.0 i niżej | netstandard2.0 | poprzednie API |
| 26.8.0 i wyżej | netstandard2.1 | obecne 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(...) / WebFarmOptions | Poprzednia |
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.js | Poprzednia |
builder.Services.AddDoconut(...) | Obecna |
app.UseDoconutResources() plus app.UseDoconut() with no arguments | Obecna |
Viewer supplied by dependency injection | Obecna |
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:
| Host | Czy 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 wersja | Nie |
.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ą
- Utwórz gałąź i wdrażalną kopię zapasową istniejącej aplikacji.
- Zanotuj dokładne wersje pakietów core i pluginów.
- Sporządź inwentaryzację każdego wywołania
new Viewer(...), wywołaniaInitCache(), wywołania ładowania licencji, mapowaniaUseDoconutWebFarm, kontrolera konwersji, skopiowanego skryptu Doconut, niestandardowej akcji paska narzędzi, wywołania zwrotnego viewer oraz punktu końcowego otwierania dokumentu. - Zachowaj bieżące pliki
.licoraz sekrety wdrożeniowe poza kontrolą wersji. - Zbierz reprezentatywny zestaw dokumentów PDF, Office, obrazów, CAD, e‑maili, DICOM, przeszukiwalnych, chronionych hasłem i anotowanych.
- 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.
| Przed | Teraz |
|---|---|
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ę:
dotnet add package Doconut.NETStandardAby uzyskać powtarzalną migrację do wydania audytowanego w tym przewodniku, przekaż wersję jako oddzielną opcję:
dotnet add package Doconut.NETStandard --version 26.8.0Utrzymuj 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:
LicenseStream > LicenseContent > LicensePath > automatic discoveryAutomatyczne 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:
// 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:
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. WstrzyknijDoconut.Viewerdo swojego kontrolera lub użyj@inject Doconut.Viewer Viewerw widoku Razor.UseDoconutResources()zastępuje ręczne podłączanieapp.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ą
| Poprzednio | Teraz |
|---|---|
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:
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:
- wywołaj
UseSession()przed Doconut, gdy zabezpieczenie sesji jest włączone; - wywołaj
UseDoconutResources()przedUseDoconut(); - utrzymuj
ResourcesPath, generowane adresy URL zasobów orazResPathklienta w zgodzie; - utrzymuj mapowaną gałąź i
BasePathklienta 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:
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(...):
// 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:
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ł.
// 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:
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:
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 */;
}, "/"));| Przed | Teraz |
|---|---|
WebFarmOptions.Path | FileShareConfig.RootPath |
PageWaitTimeSeconds / StartWaitFromPage | zniknęł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 / WebfarmPath | wciąż 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
RootPathlubUsePerTokenSubfoldersróż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:
builder.Services.AddDoconut(o => o.AddPlugin<ConverterPlugin>());// 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
*ConfigConverterdla każdej rodziny (WordConfigConverter,ExcelConfigConverter, …), każdy z zagnieżdżonym wyliczeniemEnTargetFormat— usunięto. Teraz istnieje jedno wyliczenieConversionTargetdla każdej rodziny. viewer.Converter.GetConverter()— usunięto. WstrzyknijDoconut.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:
// 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ę
| Poprzednio | Teraz |
|---|---|
DoconutOptions.UnSafeMode | UnsafeMode |
DocOptions.IsWebfarm | IsWebFarm |
DocOptions.WebfarmPath | WebFarmPath |
DocOptions.ImageResolution | wciąż 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:
| Obszar | Obecny typ |
|---|---|
| Ścieżki middleware, licencjonowanie, rejestracja wtyczek | DoconutOptions |
| Hasło, limit czasu, bezpieczeństwo, znak wodny | DocOptions |
| Renderowanie formatu i DPI | PdfConfig, WordConfig, ExcelConfig, oraz inne typy BaseConfig |
| Domyślne ustawienia widżetu przeglądarki | ViewerConfig lub równoważne opcje JavaScript |
| Generowany CSS i skrypty | CssConfig i ScriptConfig |
| Współdzielona pamięć i dostawcy chmury | FileShareConfig 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:
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
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:
- wyemituj CSS przeglądarki oraz licencjonowany CSS wyszukiwania/adnotacji przy użyciu
ReferenceCss; - wygeneruj pasek narzędzi przeglądarki należący do aplikacji;
- wygeneruj
searchBarMount,annBarMountoraz wymagany montaż przeglądarki; - wyemituj skrypty przeglądarki i licencjonowanych modułów przy użyciu
ReferenceScripts; - załaduj własny skrypt pomocniczy paska narzędzi aplikacji;
- zainicjalizuj jedną instancję
objViewer; - zainicjalizuj licencjonowane wstążki wyszukiwania i adnotacji;
- wywołaj
attach(objViewer)na każdej wstążce; - 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:
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:
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ń
- Potwierdź, że framework hosta może konsumować netstandard2.1. Jeśli nie, zatrzymaj się.
- Zaktualizuj pakiet do wersji 26.8.0 i zbuduj. Rozwiąż błędy kompilacji — większość to linie
usingw §1. - Przenieś uruchamianie do
AddDoconut()i wywołania middleware do ich nowej kolejności (§3, §4). - Wstrzyknij
Viewertam, gdzie go tworzono, uczynOpenDocumentasynchronicznym i usuńInitCache()(§5, §6). - Jeśli używasz farmy webowej, wykonaj §7 — jedyna część, która jest przeprojektowaniem, a nie zmianą nazwy.
- Jeśli konwertujesz dokumenty, wykonaj §8.
- Wykonaj §11 — zmiany po stronie klienta. To one, które nie ogłoszą się same.
- 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
202zamiast 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?