Міграція до .NET Standard 2.1

Перенесення існуючого застосунку Doconut.NETStandard з 26.7.0 до 26.8.0

Doconut має два окремих інтеграції .NET Standard. Вони використовують одну й ту ж назву пакету Doconut.NETStandard, тому визначте покоління за версією та API у застосунку перед зміною пакетів, запуску, ліцензій або ресурсів браузера.

Версія — це розвилка

Обидва покоління публікуються під однаковим ідентифікатором пакету. Тільки версія розрізняє їх:

ВерсіяЦільAPI
26.7.0 і нижчеnetstandard2.0попередній API
26.8.0 і вищеnetstandard2.1поточний API

Збільшення номеру версії — це оновлення. Не існує окремого пакету для встановлення і сумісного shim — 26.8.0 має іншу поверхню API. Очікуйте помилки компіляції після оновлення; решта цього посібника — це їх список.

Яку інтеграцію ви використовуєте?

Якщо проєкт містить…Покоління
new Viewer(_cache, _accessor, ...)Попереднє
viewer.OpenDocument(...) (синхронний)Попереднє
viewer.InitCache()Попереднє
UseDoconut(new DoconutOptions { ... })Попереднє
UseDoconutWebFarm(...) / WebFarmOptionsПопереднє
Viewer.DoconutLicense(...) або Viewer.SetLicensePlugin(...)Попереднє
viewer.Converter.GetConverter()Попереднє
using Doconut.Configs; / using Doconut.Models;Попереднє
Вручну скопійовано docViewer.js, documentLinks.js або docViewer.UI.jsПопереднє
builder.Services.AddDoconut(...)Поточне
app.UseDoconutResources() плюс app.UseDoconut() без аргументівПоточне
Viewer, наданий через впровадження залежностейПоточне
await viewer.OpenDocumentAsync(...)Поточне

Якщо обидві колонки присутні в одному застосунку, вважавайте міграцію неповною. Не надсилайте токен документа через ресурси або middleware іншого покоління.

Спершу перевірте хост‑фреймворк

Це жорстка перевірка, а не уподобання. Поточний пакет орієнтується на netstandard2.1:

ХостМоже споживати 26.8.0
.NET Core 3.0 або новіший (включаючи .NET 5/6/7/8)Так
.NET Framework, будь-яка версіяНі

.NET Framework не може посилатися на бібліотеку netstandard2.1. Якщо застосунок працює на .NET Framework, зупиніться тут і використайте пакет Doconut.NETFramework замість; починаючи з 26.9.0 він вимагає .NET Framework 4.7.2. Обидва референтні застосунки для цього випуску орієнтуються на net8.0.

Перед міграцією

  1. Створіть гілку та розгортальний резерв існуючого застосунку.
  2. Запишіть точні версії основного та плагін‑пакетів.
  3. Складіть інвентаризацію кожного виклику new Viewer(...), виклику InitCache(), виклику завантаження ліцензії, відображення UseDoconutWebFarm, контролера конверсії, скопійованого скрипту Doconut, користувацької дії панелі інструментів, зворотного виклику переглядача та кінцевої точки відкриття документа.
  4. Збережіть поточні файли .lic та секрети розгортання поза системою контролю версій.
  5. Збережіть представницький набір PDF, Office, зображень, CAD, електронної пошти, DICOM, документів, що підлягають пошуку, захищених паролем, та анотованих документів.
  6. Запишіть існуючі тайм‑аути сесії, поведінку безпеки, шрифти та налаштування платформи.

Перенесіть одне середовище перед зміною продакшну. Поточна інтеграція змінює час життя сервісу, маршрутизацію запитів, власність сесії, доставку ресурсів клієнту і — якщо ви працюєте з фермою — спосіб, яким сторінки потрапляють у браузер.

1. Простори імен: майже все переміщено до кореня

Типи конфігурації були розподілені по чотирьох просторах імен. Тепер вони всі знаходяться в Doconut.

ДоПісля
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;без змін
using Doconut.Middleware;без змін

Назви типів не змінилися: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, CloudUploadConfig, AzureConfig, CDNConfig, FileShareConfig і решта все ще присутні. У більшості файлів повна правка полягає у видаленні двох рядків using.

Doconut.Configs.Editor (BaseConfigEditor, PdfConfigEditor) було видалено і немає заміни в цьому пакеті. Якщо ваш застосунок посилався на ці типи, сплануйте цю частину окремо і не розглядайте її як частину цієї міграції.

2. Сумісність пакетів та ліцензій

Навмисно замінюйте або оновлюйте основний пакет; не покладайтеся на ідентичний ідентифікатор пакету для вибору нового API. Команда за замовчуванням встановлює останню стабільну версію:

bash
dotnet add package Doconut.NETStandard

Для відтворюваної міграції до випуску, перевіреного в цьому посібнику, передайте версію як окрему опцію:

bash
dotnet add package Doconut.NETStandard --version 26.8.0

Тримайте всі плагіни Doconut на тій самій версії, що й основний пакет — Doconut.NETStandard.Converter і Doconut.NETStandard.Dicom. Поточна інтеграція завантажує ліцензії один раз під час AddDoconut(), використовуючи таку пріоритетність:

text
LicenseStream > LicenseContent > LicensePath > automatic discovery

Автоматичне виявлення шукає Doconut.Viewer.lic та супутні файли Doconut.Viewer.<Capability>.lic. Попередні статичні виклики Viewer.DoconutLicense(...) і Viewer.SetLicensePlugin(...) не є поточним механізмом запуску, так само як і List<string> шляхів ліцензій, які приймав старий конструктор Viewer. Перемістіть ліцензію до DoconutOptions, тримайте супутні файли разом при використанні автоматичного виявлення, перезапустіть після зміни ліцензії та перевірте можливості через IDoconutLicenseService.

Не слід припускати, що наявність старої ліцензії плагіна доводить право на поточну збірку плагіна. Тестуйте Viewer, Search, Annotation, Converter та DICOM окремо з затвердженими артефактами випуску.

3. Запуск та впровадження залежностей

Раніше Viewer створювався для кожного запиту, і параметри передавалися в middleware:

csharp
// Попередня інтеграція — лише для порівняння; не компілюйте це проти поточного SDK.
var viewer = new Viewer(_cache, _accessor);
// …
appBranch.UseDoconut(new DoconutOptions { UnSafeMode = false, ShowDoconutInfo = false });

Поточна інтеграція реєструє Doconut один раз і отримує Viewer через впровадження залежностей:

csharp
builder.Services.AddDoconut(options =>
{
    options.UnsafeMode      = false;   // зауважте зміну написання: UnSafeMode → UnsafeMode
    options.ShowDoconutInfo = false;
    options.LicensePath     = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // стан сесії потребує кешу (MVC/Razor Pages вже додає один)
builder.Services.AddSession();

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

Viewer — це транзієнтний сервіс. Менеджер сесій документів та його кеш володіють довготривалим станом документу, а не конкретним інжектованим екземпляром Viewer.

Три речі, які треба перенести:

  • new Viewer(cache, accessor) більше не існує. Інжектуйте Doconut.Viewer у ваш контролер або використовуйте @inject Doconut.Viewer Viewer у Razor‑виді.
  • UseDoconutResources() замінює ручне підключення app.UseMiddleware<EmbeddedResourceMiddleware>() і має виконуватись перед гілкою документу.
  • UnSafeMode → UnsafeMode. Перейменування на один символ, яке спіймає компілятор.

Коли UnsafeMode є false, SDK перевіряє токен сесії щодо вихідного запиту, тому AddSession() / UseSession() мають залишатися в конвеєрі, UseSession() перед гілкою.

Методи, які більше не існують

РанішеЗараз
viewer.OpenDocument(path, config, options)await viewer.OpenDocumentAsync(path, config, options)
viewer.InitCache()видалено — немає нічого, що треба вручну прогрівати; видаліть виклик і будь‑який прапорець «чи я вже ініціалізував?», що його оточує
viewer.ExportToPng(sharedPath)див. §7
viewer.ExportToCloud(cloudConfig)див. §7
using var v = new Viewer(...); v.CloseDocument(t)viewer.CloseDocument(token) на інжектованому екземплярі

4. Middleware та маршрутизація ресурсів

UseDoconut() тепер не приймає аргументів. Форма гілки MapWhen сама по собі не потребує зміни — лише middleware всередині неї:

csharp
app.UseDoconutResources();   // ПЕРЕД гілкою

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

У поточному конвеєрі:

  1. викликати UseSession() перед Doconut, доки увімкнено безпеку сесії;
  2. викликати UseDoconutResources() перед UseDoconut();
  3. зберігати ResourcesPath, згенеровані URL‑адреси ресурсів та клієнтський ResPath узгодженими;
  4. зберігати узгодженою гілку, яку ви мапите, та клієнтський BasePath.

MiddlewarePath — це перевірена конфігурація; вона не створює гілку ASP.NET Core сама по собі.

5. Конструювання та життєвий цикл переглядача

Видаліть кеші, що належать застосунку, об’єктів Viewer. У Viewer більше нічого немає, що варто зберігати: він не містить стану документа, а кеш сеансу володіє всім, що переживає запит. Впровадьте його в кінцеву точку, Razor‑сторінку, контролер або scoped службу застосунку:

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

Повернутий токен ідентифікує серверну сесію документа. Ставте його як облікові дані носія: не реєструйте, не зберігайте і не передавайте в аналітику.

6. Відкриття та закриття документів

Замініть синхронний OpenDocument(...) на OpenDocumentAsync(...):

csharp
// Поточна інтеграція: Viewer надходить з DI, а відкриття документа є асинхронним.
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });

Поточні перевантаження приймають шлях до файлу або потік, необов’язкову конфігурацію формату, необов’язковий DocOptions та токен скасування. Закрийте серверну сесію явно, коли браузер більше її не потребує:

csharp
viewer.CloseDocument(token);

Видаліть будь‑який виклик InitCache() та прапорець, що його захищає — нічого не потрібно прогрівати вручну. Не використовуйте повторно токен, створений попередньою бібліотекою після переходу: відкривайте кожен документ знову через поточний API.

7. Web‑ферма → розподілена: найбільша зміна

UseDoconutWebFarm and WebFarmOptions більше не існують. Якщо ваш застосунок їх викликає, цей розділ — ваше оновлення; якщо ні, перейдіть до §8.

Раніше один middleware робив усе: він обслуговував попередньо відрендерені зображення з спільної папки, і опитував, поки інший вузол ще їх записував.

csharp
// Попередня інтеграція — один виклик, неявна координація через файлову систему.
appBranch.UseDoconutWebFarm(new WebFarmOptions
{
    Path                = Path.Combine(env.WebRootPath, "webfarm"),
    PageWaitTimeSeconds = 180,
    StartWaitFromPage   = 5,
});

Те саме завдання тепер розділено на дві явні частини. Write side — вузол, який відкриває документ, публікує весь набір артефактів (сторінки, інформація про документ, індекс пошуку, метадані) у спільному ресурсі:

csharp
var result = await _publisher.PublishAsync(          // DistributedDocumentPublisher, впроваджений з DI
    pathToFile,
    new FileShareConfig
    {
        Location              = CloudLocation.FileShare,
        RootPath              = @"\\fileserver\doconut",   // те саме теку, яку ви використовуєте сьогодні
        UsePerTokenSubfolders = true,
    },
    config,
    documentOptions,
    new DistributedDocumentPublishOptions
    {
        CleanUpStagingDirectory = true,
        FirstPagePriority       = true,
    });

return Content(result.Token);

Read side — будь‑який вузол обслуговує з спільного ресурсу:

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 = /* те SAME FileShareConfig, як вище */;
    }, "/"));
РанішеЗараз
WebFarmOptions.PathFileShareConfig.RootPath
PageWaitTimeSeconds / StartWaitFromPageзникло — замінено на FirstPagePriority на стороні запису плюс FileShareConfig.ReadReadyPollMs на стороні читання
viewer.OpenDocument(...) потім viewer.ExportToPng(share)один виклик PublishAsync(...)
DocOptions.IsWebfarm / WebfarmPathвсе ще є, написано IsWebFarm / WebFarmPath — але не потрібен у шляху публікації

Ваша топологія не змінюється. Вкажіть RootPath на той самий UNC‑шар і кожен вузол продовжуватиме працювати так, як зараз. Змінюється лише те, що публікація — це операція, яку ви викликаєте, а не побічний ефект рендерингу.

Обидві половини повинні узгоджуватись. Якщо RootPath або UsePerTokenSubfolders різняться між видавцем і обробником, інший вузол відповість 404. Створіть конфігурацію в одному допоміжному модулі і викликайте її з обох сторін.

PageWaitTimeSeconds = 180 означав «блокувати до трьох хвилин в очікуванні появи сторінки». Заміну є явною: з FirstPagePriority = true, сторінка 1 доступна одразу, а наступні сторінки відповідають HTTP 202 Accepted, доки не будуть записані. Вбудований переглядач автоматично повторює запит, коли встановлено retryOn409. Клієнт, який не повторює, побачить пошкоджені плитки для сторінок, що ще рендеряться.

Повний порядок, включаючи фонову публікацію та квитки доступу, описано у статті Розподілені розгортання.

8. Конвертація — це плагін, і набагато менший

Зареєструйте плагін, а потім впровадьте фасад DocumentConverter:

csharp
builder.Services.AddDoconut(o => o.AddPlugin<ConverterPlugin>());
csharp
// Попередня інтеграція
var converter = viewer.Converter.GetConverter();
var config    = new WordConfigConverter { TargetFormat = WordConfigConverter.EnTargetFormat.PDF };
var result    = converter.Convert(stream, SourceFormatConverter.DOCX, config);

// Поточна інтеграція
var result = await _converter.ConvertAsync(stream, ".docx", ConversionTarget.Pdf, null, ct);

Що це замінює:

  • SourceFormatConverter — видалено. Передайте розширення файлу як рядок, включаючи крапку.
  • Типи *ConfigConverter для кожної сім'ї (WordConfigConverter, ExcelConfigConverter, …), кожен з вкладеним перерахуванням EnTargetFormat — видалено. Тепер для кожної сім'ї існує одне перерахування ConversionTarget.
  • viewer.Converter.GetConverter() — видалено. Впровадьте Doconut.DocumentConverter.

ConvertAsync повертає поток, який підтримує пошук, тому return File(result, mime, name) працює безпосередньо — копія старого коду MemoryStream більше не потрібна. У постаченому прикладі це видалило 68‑випадковий перемикач розширень та десять майже ідентичних контролерів.

Перегляньте Плагін Конвертера для повного огляду.

9. Хмарні провайдери

UseDoconutCloud став універсальним. Провайдер — це аргумент типу замість значення Location, яке переключалося всередині проміжного програмного забезпечення:

csharp
// Попередня інтеграція
appBranch.UseDoconutCloud(new CloudOptions { Location = CloudLocation.CDN, ... });

// Поточна інтеграція
branch.UseDoconutCloud<CDNCloudHandler>(options =>
{
    options.Location          = CloudLocation.CDN;
    options.CloudUploadConfig = new CDNConfig { DoconutCdnUrl = "..." };
}, "/");

Класи конфігурації залишилися без змін, окрім простору імен (Doconut.Configs.Cloud → Doconut.Clouds): AzureConfig, AmazonConfig, GoogleCloudConfig, DropBoxConfig, RedisConfig, CDNConfig, FTPConfig, а також новий FileShareConfig. Обробники названі <Provider>CloudHandler.

Обробник CDN є тільки для читання — він обслуговує те, що вже знаходиться на CDN; він не завантажує.

10. Об’єкти конфігурації, які змінили назву

РанішеЗараз
DoconutOptions.UnSafeModeUnsafeMode
DocOptions.IsWebfarmIsWebFarm
DocOptions.WebfarmPathWebFarmPath
DocOptions.ImageResolutionвсе ще присутній, але застарілий — встановіть роздільну здатність у конфігурації формату

DocOptions також отримує IsSecured.

Поточний API також розділяє обов’язки суворіше, ніж попередній, тому перевірте, що кожне налаштування знаходиться в об’єкті, який тепер його володіє:

ПитанняПоточний тип
Шляхи проміжного ПЗ, ліцензування, реєстрація плагінівDoconutOptions
Пароль, тайм‑аут, безпека, водяний знакDocOptions
Відображення формату та DPIPdfConfig, WordConfig, ExcelConfig, та інші типи BaseConfig
Типові налаштування віджету браузераViewerConfig або еквівалентні параметри JavaScript
Згенерований CSS та скриптиCssConfig і ScriptConfig
Спільне сховище та хмарні провайдериFileShareConfig та інші конфігурації Doconut.Clouds

Не використовуйте DocOptions.ImageResolution як елемент керування рендерингом. Він застарілий; встановіть BaseConfig.ImageResolution у конфігурації, специфічній для формату. Перегляньте всі типові значення, замість того щоб припускати, що попередня конфігурація має таку ж поведінку.

11. Клієнтський переглядач — два зміни, які тихо не працюють

Обидві ці зміни не впливають на роботу сервера. Ваш документ відображається, сторінка виглядає правильно, і в консолі браузера нічого не з’являється. Прочитайте цей розділ, навіть якщо ваш C# компілюється з першої спроби.

Зворотні виклики переглядача тепер є параметрами, а не глобальними функціями

Попередній переглядач викликав ваші обробники за іменем, отримуючи назву глобальної функції з ідентифікатора контейнера. Достатньо було оголосити function ctlDoc_OnViewerReady() на сторінці з <div id="div_ctlDoc">. Поточний переглядач приймає явні зворотні виклики в об’єкті параметрів і більше не шукає ці глобальні функції:

javascript
objctlDoc = $("#div_ctlDoc").docViewer({
    // ... ваші існуючі параметри ...
    onViewerBusy:     ctlDoc_OnViewerBusy,      // було знайдено за назвою
    onViewerReady:    ctlDoc_OnViewerReady,     // було знайдено за назвою
    onCopy:           ctlDoc_Copy,              // було ctlDoc_Copy(text)
    onAutoLoadStatus: ctlDoc_AutoLoadStatus     // було ctlDoc_AutoLoadStatus(page)
});

Чому це неприємно: старий виклик був обгорнутий у порожній catch, який поглинув усе. Тепер ваші функції просто не виконуються, і нічого не повідомляє про помилку. Типовий симптом — індикатор завантаження, який ніколи не зупиняється, — тому що функція, що його ховала, була ctlDoc_OnViewerReady. Документ за цим у порядку.

Повний список параметрів: onPageLoading, onPageLoaded, onThumbnailClicked, onPageClicked, onDoubleClick, onViewerBusy, onViewerReady, onViewerError, onCopy, onAnnSaved, onAnnSaveError, onAnnLoaded, onAnnClosed, onAutoLoadStatus, onThumbsShown та onError. Не існує зворотного виклику при кліку на посилання: обробка гіперпосилань вбудована, керується showHyperlinks.

ResPath має вказувати на префікс ресурсу

javascript
ResPath: '',                      // РАНІШЕ — ресурси надходили з кореня застосунку
ResPath: 'doconut-res/images',    // ЗАРАЗ    — префікс UseDoconutResources() підключає

Якщо ви змінили префікс за допомогою DoconutOptions.ResourcesPath, використайте це значення замість нього.

12. Панель інструментів переглядача, Пошук та Анотація

Не мігруйте старі скрипти по одному. Поточні довідкові застосунки формують один повний пакет сторінки:

  1. випустити CSS переглядача та ліцензований CSS Пошуку/Анотації за допомогою ReferenceCss;
  2. вивести панель інструментів переглядача, що належить застосунку;
  3. вивести searchBarMount, annBarMount та необхідний монтувальний елемент переглядача;
  4. випустити скрипти переглядача та ліцензованих модулів за допомогою ReferenceScripts;
  5. завантажити власний допоміжний скрипт панелі інструментів застосунку;
  6. ініціалізувати один objViewer;
  7. ініціалізувати ліцензовані стрічки Пошуку та Анотації;
  8. викликати attach(objViewer) для кожної стрічки;
  9. відкрити документ і викликати objViewer.View(token).

Пошук та Анотація — це модулі, приєднані до того ж переглядача, а не незалежні панелі інструментів. Основна панель інструментів належить хост-застосунку; стрічки Пошуку та Анотації вбудовані, доступ до них регулюється можливостями.

Видаліть вручну скопійовані файли, такі як documentLinks.js і docViewer.UI.js, лише після того, як поточна сторінка працюватиме з ресурсами, випущеними ReferenceCss та ReferenceScripts.

13. Реєстрація плагінів

Статичні методи ліцензування плагінів не реєструють поточні плагіни. Встановіть і явно зареєструйте кожен випущений пакет:

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

AddDoconut() перевіряє зареєстровані можливості плагінів під час запуску. Converter і DICOM — це випущені плагіни .NET Standard. Звичайний Пошук і Анотація — вбудовані ліцензовані функції, а не пакети AddPlugin<TPlugin>().

14. Сесія та безпека документів

Поточна інтеграція прив'язує документи до непрозорих токенів та кешованих сесій. За замовчуванням UnsafeMode = false, UseDoconut() додає безпеку доступу до документів, і хост повинен налаштувати сесію ASP.NET:

csharp
builder.Services.AddDistributedMemoryCache(); // стан сесії потребує кеша (MVC/Razor Pages вже додає один)
builder.Services.AddSession();
app.UseSession();

Залишайте DocOptions.IsSecured = true, якщо лише переглянутий дизайн не вимагає іншого. Ніколи не використовуйте UnsafeMode = true як швидкий шлях міграції на одному вузлі. Тестуйте запити без токену, з пошкодженим токеном, з простроченим токеном та з токеном з іншої сесії браузера.

У фермі запит сторінки може потрапити на вузол, який ніколи не бачив початкового запиту, тому перевірка per-session його відхилить. Це єдиний випадок, коли UnsafeMode = true є правильним — і його слід поєднувати з підписаними квитками доступу через AddDoconutDistributedDocumentSecurity, а не розповсюджувати окремо. Дивіться Розподілені розгортання.

Примітка щодо іменування

У всіх фреймворках клас має назву Viewer. Якщо ви знайдете DocumentViewer у старих фрагментах коду або статтях сторонніх розробників, такого типу ніколи не існувало в SDK.

15. Пропонований порядок робіт

  1. Переконайтеся, що хост-фреймворк може споживати netstandard2.1. Якщо ні — зупиніться.
  2. Оновіть пакет до 26.8.0 і зберіть. Виправте помилки компіляції — більшість це рядки using у §1.
  3. Перемістіть запуск до AddDoconut(), а виклики middleware — у їх новий порядок (§3, §4).
  4. Вставте Viewer там, де ви його конструювали, зробіть OpenDocument асинхронним і видаліть InitCache() (§5, §6).
  5. Якщо ви використовуєте веб-ферму, виконайте §7 — єдина частина, яка потребує редизайну, а не лише перейменування.
  6. Якщо ви конвертуєте документи, виконайте §8.
  7. Виконайте §11 — зміни на стороні клієнта. Це ті, які не будуть оголошені самі по собі.
  8. Відкрийте реальний документ у браузері та спостерігайте за індикатором завантаження. Зелене збірка нічого не доводить: ліцензування, реєстрація плагінів, шлях до ресурсу та зворотні виклики переглядача падають лише під час виконання. Для ферми перевірте, що документ, опублікований одним вузлом, обслуговується іншим.

Тестування міграції

Принаймні, перевірте:

  • запуск програми з виробничою ліцензією та усіма зареєстрованими плагінами;
  • CSS/скрипти Viewer та всі запити сторінка-зображення за вибраними шляхами;
  • відкриття документа, навігація, масштабування, мініатюри, друк та явне закриття;
  • пошук у документі, що містить текст, та стан не‑пошукового файлу лише з зображенням;
  • завантаження, збереження, експорт анотацій та контроль можливостей;
  • виявлення цільових форматів конвертера, вивід, завантаження та стан водяного знака;
  • сторінки DICOM, кадри та анімація; технічні метадані недоступні в цьому пакеті;
  • документи, захищені паролем, власні шрифти, нелатинський текст та налаштовані тайм‑аути;
  • відхилення токену між сесіями та поведінка при закінченні сесії;
  • для ферми: опублікувати на одному вузлі, запросити пізню сторінку з іншого та підтвердити, що viewer повторює відповіді 202 замість показу пошкоджених плиток;
  • мобільний, темний режим та шлях виробничого reverse-proxy.

План відкату

Зберігайте попередній артефакт розгортання, відповідні пакети, файли ліцензій та скопійовані ресурси браузера разом. Безпечний відкат переключає всю генерацію застосунку; він не змішує сервер попередньої генерації з поточними скриптами або поточний сервер з викликами new Viewer(...).

Перед переходом задокументуйте:

  • слот розгортання або артефакт, використаний для відкату;
  • вплив спільного сховища, якщо є — артефакти, опубліковані в 26.8.0, не споживаються попереднім проміжним ПЗ веб‑ферми;
  • як активні сесії документів будуть анульовані;
  • перевірка стану та тестовий документ, використані для рішення про відкат;
  • хто може відновити попередній набір пакетів та конфігурацію.

Спадкова документація

Перекладений попередній посібник доступний за адресою Наслідувана настройка .NET Standard. Попередній шлюз інтеграції пояснює ті ж сигнали ідентифікації та посилається назад на цей посібник з міграції.

Зберігайте історичну URL у закладках та заявках підтримки, доки встановлення netstandard2.0 ще існують. Вона документує інше покоління і не перенаправляється на поточний API.

Чи була ця сторінка корисною?