Міграція до .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, користувацької дії панелі інструментів, зворотного виклику Viewer та кінцевої точки відкриття документу.
  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. Проміжне ПЗ та маршрутизація ресурсів

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, які належать додатку. У 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 farm → distributed: найбільша зміна

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

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

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

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

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);

Сторона читання — будь‑який вузол обслуговує з спільного ресурсу:

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 = /* той самий 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, доки не будуть записані. Вбудований viewer автоматично повторює запит, коли встановлено 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({
    // ... your existing options ...
    onViewerBusy:     ctlDoc_OnViewerBusy,      // was found by name
    onViewerReady:    ctlDoc_OnViewerReady,     // was found by name
    onCopy:           ctlDoc_Copy,              // was ctlDoc_Copy(text)
    onAutoLoadStatus: ctlDoc_AutoLoadStatus     // was 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: '',                      // BEFORE — ресурси надходили з кореня застосунку
ResPath: 'doconut-res/images',    // NOW    — префікс, який монтує UseDoconutResources()

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

12. Панель інструментів Viewer, пошук та анотації

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

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

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

Видаліть вручну скопійовані файли, такі як 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() і виклики проміжного ПЗ у їх новий порядок (§3, §4).
  4. Впровадьте Viewer там, де ви його створювали, зробіть OpenDocument асинхронним і видаліть InitCache() (§5, §6).
  5. Якщо ви використовуєте веб‑ферму, виконайте §7 — єдина частина, що потребує редизайну, а не лише перейменування.
  6. Якщо ви конвертуєте документи, виконайте §8.
  7. Виконайте §11 — зміни на боці клієнта. Це ті, які не повідомлятимуть про себе.
  8. Відкрийте реальний документ у браузері і спостерігайте за індикатором завантаження. Зелене збірка нічого не доводить: ліцензування, реєстрація плагінів, шлях до ресурсів і зворотні виклики Viewer падають лише під час виконання. Для ферми перевірте, що документ, опублікований одним вузлом, обслуговується іншим.

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

Мінімум, перевірте:

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

План відкату

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

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

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

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

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

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

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