Миграция с классической интеграции .NET 6

Перенос существующего приложения Doconut.NET6 на текущий DI и асинхронный API

Doconut имеет две отдельные интеграции .NET 6. Они могут использовать одно и то же имя пакета Doconut.NET6, поэтому определите поколение по API в приложении перед изменением пакетов, стартапа, лицензий или ресурсов браузера.

Какую интеграцию .NET 6 вы используете?

Если проект содержит…Поколение
app.MapWhen(... "DocImage.axd" ...)Унаследованная / классическая
new Viewer(_cache, _accessor, ...)Унаследованная / классическая
Viewer.DoconutLicense(...) или Viewer.SetLicensePlugin(...)Унаследованная / классическая
Вручную скопированные docViewer.js, documentLinks.js или docViewer.UI.jsУнаследованная / классическая
builder.Services.AddDoconut(...)Текущая интеграция
app.UseDoconutResources() плюс app.UseDoconut()Текущая интеграция
Viewer, полученный через внедрение зависимостейТекущая интеграция
await viewer.OpenDocumentAsync(...)Текущая интеграция

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

Почему имя пакета NuGet может вас вводить в заблуждение

Обе генерации распространялись под идентификатором пакета Doconut.NET6. Ссылка на пакет, lock‑файл или кэшированный .nupkg поэтому не определяют используемое API самостоятельно. Зафиксируйте точную версию пакета и проверьте Program.cs, создание viewer, открытие документов и скрипты браузера совместно.

Текущий релиз, проверенный для данного руководства, — Doconut.NET6 26.7.0. Его необязательные публичные пакеты — Doconut.NET6.Converter и Doconut.NET6.Dicom, привязанные к той же версии, что и основной пакет.

Перед миграцией

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

Мигрируйте одну среду перед изменением продакшн. Текущая интеграция меняет время жизни сервисов, маршрутизацию запросов, владение сеансом и доставку клиентских ресурсов.

Совместимость пакетов и лицензий

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

bash
dotnet add package Doconut.NET6

Для воспроизводимой миграции к релизу, проверенному этим руководством, укажите версию отдельным параметром:

bash
dotnet add package Doconut.NET6 --version 26.7.0

Держите каждый плагин Doconut на той же версии, что и основной пакет. Текущая интеграция загружает лицензии один раз во время AddDoconut(), используя такой порядок приоритета:

text
LicenseStream > LicenseContent > LicensePath > automatic discovery

Автоматическое обнаружение ищет файлы Doconut.Viewer.lic и сопутствующие Doconut.Viewer.<Capability>.lic. Классический вызов Viewer.DoconutLicense(...) или Viewer.SetLicensePlugin(...) не является текущим механизмом стартапа. Переместите лицензию в DoconutOptions, храните сопутствующие файлы вместе при использовании автоматического обнаружения, перезапустите приложение после изменения лицензии и проверьте возможности через IDoconutLicenseService.

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

Запуск и внедрение зависимостей

Классические приложения создают Viewer с зависимостями кэша ASP.NET и доступа к запросу:

csharp
// Classic integration — contrast only; do not compile this against the current SDK.
var viewer = new Viewer(_cache, _accessor, licenseFilePath);

Текущая интеграция регистрирует Doconut один раз и получает Viewer через внедрение зависимостей:

csharp
builder.Services.AddDoconut(options =>
{
    options.LicensePath = "Doconut.Viewer.lic";
    options.UnsafeMode = false;
});
builder.Services.AddSession();

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

Viewer объявлен как transient‑service. Менеджер сеанса документа и его кэш владеют более долгоживущим состоянием документа, а не конкретным внедрённым экземпляром Viewer.

Middleware и маршрутизация ресурсов

Удалите классическую ветку MapWhen, определяющую DocImage.axd:

csharp
// Classic integration — remove during the cutover.
app.MapWhen(
    context => context.Request.Path.ToString().EndsWith("DocImage.axd"),
    branch => branch.UseDoconut(new DoconutOptions()));

В текущем конвейере:

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

MiddlewarePath — проверенная конфигурация; она сама по себе не создаёт ветку ASP.NET Core. Используйте либо простой конвейер из примера выше, либо явный вызов app.Map("/doconut", branch => branch.UseDoconut()), применяемый последовательно клиентом.

Конструирование 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 });
});

Возвращённый токен идентифицирует серверный сеанс документа. Обращайтесь с ним как с токеном‑носителем: не логируйте его, не сохраняйте и не помещайте в аналитику.

Открытие и закрытие документов

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

csharp
// Current .NET 6 integration: Viewer comes from DI and document opening is asynchronous.
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });

Текущие перегрузки принимают путь к файлу или поток, необязательную конфигурацию формата, опциональный DocOptions и токен отмены. Закрывайте серверный сеанс явно, когда браузер больше не нуждается в нём:

csharp
viewer.CloseDocument(token);

Не переиспользуйте классический токен после перехода. Открывайте каждый документ заново через текущий API.

Классы конфигурации

Текущий API разделяет ответственности:

ОбластьТекущий тип
Пути middleware, лицензирование, регистрация плагиновDoconutOptions
Пароль, таймаут, безопасность, водяной знакDocOptions
Отображение формата и DPIPdfConfig, WordConfig, ExcelConfig и другие типы BaseConfig
Настройки виджетов браузераViewerConfig или эквивалентные параметры JavaScript
Сгенерированные CSS и скриптыCssConfig и ScriptConfig

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

Панель инструментов Viewer, поиск и аннотации

Не переносите старые скрипты по одному. Текущие демонстрационные приложения собирают один полный пакет страницы:

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

Search и Annotation — модули, присоединённые к тому же Viewer, а не независимые панели. Главная панель принадлежит хост‑приложению; ленты Search и Annotation — встроенные, доступные только при наличии соответствующих возможностей.

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

Регистрация плагинов

Классические статические методы лицензирования плагинов не регистрируют текущие плагины. Установите и явно зарегистрируйте каждый выпущенный пакет:

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

AddDoconut() проверяет зарегистрированные возможности плагинов при старте. Converter и DICOM — выпущенные .NET 6 плагины. Обычные Search и Annotation — встроенные лицензированные функции, а не пакеты AddPlugin<TPlugin>().

Сеанс и безопасность документов

Текущая интеграция привязывает документы к непрозрачным токенам и кэшированным сеансам. При UnsafeMode = false по умолчанию UseDoconut() добавляет безопасность доступа к документам, и хост должен настроить ASP.NET‑сеанс:

csharp
builder.Services.AddSession();
app.UseSession();

Оставляйте DocOptions.IsSecured = true, если только не проведён обзорный дизайн, требующий иного. Никогда не используйте UnsafeMode = true как короткий путь миграции. Тестируйте запросы без токена, с повреждённым токеном, с истёкшим токеном и с токеном из другой браузерной сессии.

Справочный распределённый пример добавляет билеты доступа и детали транспортировки. Эти API не требуются для обычной одноузловой миграции.

Тестирование миграции

Как минимум, проверьте:

  • запуск приложения с продакшн‑лицензией и всеми зарегистрированными плагинами;
  • CSS/скрипты Viewer и все запросы изображений страниц по выбранным путям;
  • открытие документа, навигацию, масштаб, миниатюры, печать и явное закрытие;
  • поиск в текстовом документе и отсутствие поиска в файле, содержащем только изображение;
  • загрузку, сохранение, экспорт аннотаций и контроль доступа к возможностям;
  • обнаружение целей Converter, вывод, загрузку и состояние водяного знака;
  • страницы DICOM, кадры и анимацию; технические метаданные .NET 6 недоступны;
  • документы, защищённые паролем, пользовательские шрифты, нелатинский текст и настроенные таймауты;
  • отклонение токенов между сессиями и поведение при истёкшей сессии;
  • мобильные устройства, тёмный режим и путь обратного прокси в продакшн.

План отката

Сохраняйте классический артефакт развертывания, соответствующие пакеты, файлы лицензий и скопированные браузерные ресурсы вместе. Безопасный откат переключает всё приложение на другое поколение; он не смешивает классический сервер с текущими скриптами и не смешивает текущий сервер с классическими вызовами DocImage.axd.

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

  • слот развертывания или артефакт, используемый для отката;
  • влияние на базу данных/кеш, если таковое имеется;
  • как будут инвалидированы активные сеансы документов;
  • проверочный документ и проверку здоровья, используемые для решения об откате;
  • кто может восстановить предыдущий набор пакетов и конфигурацию.

Устаревшая документация

Переведённое классическое руководство доступно по ссылке Устаревшая настройка .NET 6. Новый Шлюз классической интеграции объясняет те же сигналы идентификации и ссылается обратно на это руководство по миграции.

Сохраняйте исторический URL в закладках и тикетах поддержки, пока классические установки продолжают существовать. Он описывает другое поколение и не перенаправляется на текущий API.

Была ли эта страница полезной?