Як працює Viewer

Життєвий цикл запиту документа

Doconut рендерить документи як розбиті на сторінки зображення, що подаються через middleware ASP.NET Core. Розуміння життєвого циклу — відкриття, токен, запити сторінок, закриття — пояснює майже всю поведінку, яку ви спостерігатимете, включаючи повідомлення про помилки.

Три складові частини

  • Viewer — публічний сервіс, який ви інжектуєте. Він відкриває документи та повертає токени сесії.
  • Сесія документа — об’єкт на боці сервера, що зберігає завантажений документ, індексований токеном у IMemoryCache.
  • Middleware Doconut — додається за допомогою UseDoconut(); відповідає на кожен запит, який робить віджет браузера (pages, thumbnails, search, annotations, …), завжди автентифікований токеном.

Viewer без стану — за задумом

Viewer є sealed, не зберігає стан документа для кожного запиту і навмисно не реалізує IDisposable. Сесії існують незалежно в менеджері сесій і очищуються внаслідок закінчення терміну дії кешу або явного виклику CloseDocument(token).

Інжектуйте його там, де потрібно:

csharp
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
    var token = await viewer.OpenDocumentAsync($"files/{fileName}");
    return Results.Content(token, "text/plain");
});

Що відбувається всередині OpenDocumentAsync

  1. Ліцензійна перевірка. Відхилена або прострочена версія ліцензії (чорний список, підроблена або збірка поза вікном оновлення ліцензії) миттєво генерує LicenseException з причиною відхилення у повідомленні — відкриття ніколи не деградує без повідомлення для недійсної (на відміну від відсутньої) ліцензії. Ліцензія типу Temporary або підписки, прострочена за календарем, є винятком: вона не генерує виключення — переходить у водяний знак.
  2. Створення сесії. Фабрика переглядачів вибирає відповідний переглядач формату за розширенням файлу та завантажує документ (див. Rendering Pipeline). Сесія зберігається в IMemoryCache під новим GUID токеном з ковзним терміном діїDocOptions.TimeOut хвилин, за замовчуванням 60. Кожен запит сторінки скидає таймер.
  3. Реєстрація безпеки. При UnsafeMode = false (за замовчуванням) токен прив'язується до ASP.NET сесії виклику: маркер secure-{token} записується в сесію, тому лише браузерна сесія, яка відкрила документ, може запитувати його сторінки.
  4. Токен повертається. Це єдина облікова дані для всього подальшого.

Три перевантаження відрізняються лише вхідними параметрами: шлях до файлу, шлях до файлу плюс конфігурація формату (PdfConfig, WordConfig, …) або Stream плюс FileInfo, розширення якого визначає формат.

Як віджет отримує сторінки

Віджет клієнта викликає middleware Doconut з токеном у рядку запиту. Те, що робить middleware, залежить від запиту:

ЗапитПризначення
?token=…&page=NЗображення відрендереної сторінки (PNG)
?token=…&page=N&thumb=1Мініатюра
?token=…&zoom=…Рендеринг збільшеної сторінки
?token=…&search=termПовнотекстовий пошук (з ліцензійною перевіркою)
?token=…&bookmarksСтруктура/закладки документа
?token=…&copy / &showlinks / &fileFormatКопіювання тексту, гіперпосилання та інформація про формат
?token=…&metaТехнічні метадані DICOM; повертає 501 для DICOM сесії на .NET 6
?token=…&action=rotate/flip/closeДії зі сторінкою та явне закриття
?token=…&AnnSave=… / &AnnLoadЗбереження/завантаження анотацій

Кожен з цих шляхів спочатку проходить валідацію:

  • Відсутній токен → middleware повертає 404 (або банер версії, коли ShowDoconutInfo = true).
  • Невідомий або прострочений токен → зображення помилки з текстом Document session not found. Please re-open document.
  • Відсутній middleware сесії (при UnsafeMode = false) → HTTP 500 з повідомленням Session middleware not configured. Call UseSession() before UseDoconut().
  • Токен відкритий іншим браузерним сеансом → зображення помилки з текстом You Are Not Authorized To View This Page.

Закриття документа

csharp
viewer.CloseDocument(token);

CloseDocument видаляє сесію з кешу (що звільняє підлеглий движок документа і одразу звільняє пам'ять), видаляє маркер secure-{token} і відкликає доступ. Викликати його необов'язково — ковзний термін дії автоматично виконує те ж очищення — але для великих документів це ввічливий спосіб звільнити пам'ять одразу після завершення користувачем.

Основні висновки

  • Один відкритий документ = одна сесія = один токен. Токени прив'язані до браузерної сесії, а не до глобальних URL.
  • Токен прострочується за ковзним вікном; переглядач, який залишився без активності понад DocOptions.TimeOut, потребує повторного відкриття.
  • Viewer можна інжектувати та вільно ділитися; сесії містять весь стан.

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