Швидкий старт
Відобразіть ваш перший документ за кілька хвилин
Цей посібник переводить додаток ASP.NET Core з порожнього Program.cs до документа, відображеного в браузері: реєстрація сервера, повний пакет Viewer (панель інструментів Viewer, монтування Viewer та додаткові стрічки пошуку/анотації), посилання на ресурси, ініціалізація клієнта, відкриття документа та виконання.
Налаштування сервера
AddDoconut() реєструє сервіси; UseDoconutResources() і UseDoconut() підключають проміжне ПЗ. Виклик ресурсів має бути першим. Виклики сесії також потрібні — стандартна безпека документів Doconut перевіряє кожен запит сторінки проти стану сесії ASP.NET. Стан сесії потребує кешу: AddDistributedMemoryCache() забезпечує його. Додаток MVC або Razor Pages вже реєструє його, але мінімальний API‑додаток — ні, і без нього додаток зупиняється під час запуску з Unable to resolve service for type 'IDistributedCache'. Вже реєстрували Doconut під час Встановлення? Перейдіть до наступного розділу.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // стан сеансу потребує кешу (MVC/Razor Pages вже додає його)
builder.Services.AddSession(); // Безпека документів Doconut базується на стані сеансу ASP.NET
app.UseSession(); // викличте UseSession() перед UseDoconut()
app.UseDoconutResources(); // повинно бути зареєстровано перед UseDoconut()
app.UseDoconut();Для розташування шляхів у виробничому стилі, прив'яжіть проміжне ПЗ документа до явної гілки та збережіть узгодженість чотирьох налаштувань шляхів:
builder.Services.AddDoconut(options =>
{
options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
options.MiddlewarePath = "/doconut";
options.ResourcesPath = "/doconut-res";
options.UnsafeMode = false;
});
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();
app.UseRouting();
app.UseSession();
app.UseDoconutResources();
app.Map("/doconut", branch => branch.UseDoconut());MiddlewarePath — це значення координації; воно саме по собі не прив'язує гілку ASP.NET Core. У цьому прикладі хост прив'язує /doconut, тому клієнт використовує BasePath: 'doconut'. ResourcesPath подає вбудований пакет за адресою /doconut-res, а шлях до зображень віджета становить ResPath: 'doconut-res/images'. Запишіть обидва без початкового слешу: переглядач додає його сам, тому '/doconut' стане //doconut/DocImage.axd, що браузер сприймає як запит до хоста з назвою doconut, і переглядач завершує роботу з помилкою «The viewer handler could not be reached».
Додайте переглядач на сторінку
Viewer є необхідним ядром сторінки. Його поверхня рендерингу використовує два вкладені div:
<div id="divDocViewer">
<div id="div_ctlDoc"></div>
</div>Розглядайте панель інструментів, монтування модулів та поверхню Viewer як одну композицію сторінки. Пошук і
Анотація вбудовують свої стрічки у необов'язкові монтування, проте ці модулі ніколи
не працюють окремо: вони завжди приєднуються до Viewer на тій же сторінці. Використовуйте той самий порядок, що і
Doconut.TestApp і Doconut.TestApp.Distributed:
<nav id="toolbar" aria-label="Document viewer controls">
<!-- Кнопки навігації, масштабування, пошуку та анотацій Viewer -->
</nav>
<div id="searchBarMount"></div>
<div id="annBarMount"></div>
<div id="divDocViewer">
<div id="div_ctlDoc"></div>
</div>Посилання на ресурси переглядача
У Razor‑виді інжектований сервіс Viewer генерує теги <link> та <script> переглядача у порядку залежностей — віджет є плагіном jQuery, тому jQuery має бути завантажений перед скриптами переглядача:
@inject Doconut.Viewer Viewer
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
IncludeBootstrapCss = true,
IncludeViewerCss = true
}))
@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
IncludeJQuery = true,
IncludeBootstrap = true,
IncludeViewerScripts = true
}))Для повного пакету Viewer запитайте ресурси Viewer та модулів разом:
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
IncludeBootstrapCss = true,
IncludeViewerCss = true,
IncludeSearchCss = true,
IncludeAnnotationCss = true
}))
@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
IncludeJQuery = true,
IncludeBootstrap = true,
IncludeViewerScripts = true,
IncludeSearchScripts = true,
IncludeSearchBar = true,
IncludeAnnotationScripts = true,
IncludeAnnotationBar = true
}))IncludeViewerCss і IncludeViewerScripts — це обов'язкові базові прапорці. Ніколи не публікуйте приклад
стрічки Пошуку або Анотації без них, монтування Viewer та екземпляра docViewer.
ReferenceCss і ReferenceScripts пропускають ресурси необов'язкового модуля, коли
поточна ліцензія не надає таку можливість; базовий Viewer все одно запускається.
Ініціалізувати переглядач
Віджет на боці клієнта — це плагін jQuery. Це мінімальний набір реальних параметрів ініціалізації (не псевдокод):
let searchBar = null;
let annBar = null;
const objViewer = $('#div_ctlDoc').docViewer({
showThumbs: true,
autoLoad: false,
pageZoom: 100,
FitType: 'width',
BasePath: 'doconut', // без початкового '/'
ResPath: 'doconut-res/images', // без початкового '/'
onViewerReady: function () {
// сторінки видимі; безпечно приховати індикатор завантаження тут
},
// Перенаправляти події життєвого циклу анотації до вбудованої стрічки, коли вона присутня.
onAnnLoaded: () => annBar?.handleAnnLoaded(),
onAnnSaved: () => annBar?.handleAnnSaved(),
onAnnSaveError: () => annBar?.handleAnnSaveError(),
onAnnClosed: () => annBar?.handleAnnClosed(),
onError: function (message) {
console.error('Doconut viewer error:', message);
}
});Кейс параметрів дійсно змішаний — showThumbs, autoLoad і pageZoom у camelCase, а FitType, BasePath і ResPath у PascalCase. Немає послідовного правила; якщо вказати неправильний регістр, параметр буде без повідомлення проігноровано (віджет повернеться до значення за замовчуванням замість викидання помилки).
Зібрати повний пакет Переглядача
Обидві довідкові програми .NET 6 встановлюють наступні частини разом на одній сторінці:
| Частина пакету | Вимога | Як підключено |
|---|---|---|
Ресурси Переглядача, монтування та objViewer | Обов’язково | Основний рендерер документу |
| Панель інструментів Переглядача | Обов’язково у довідковій композиції | Розмітка хоста; кнопки викликають той самий objViewer |
| Стрічка пошуку | Опціональний, ліцензований модуль | doconutSearchBar(...).attach(objViewer) |
| Стрічка анотацій | Опціональний, ліцензований модуль | doconutAnnotationBar(...).attach(objViewer) |
Хоча основна панель інструментів Переглядача є розміткою хоста, вона встановлюється разом з Переглядачем і ніколи не повинна документуватись як окремий елемент управління. Це зберігає її макет, підписи, іконки та правила авторизації під контролем вашого застосунку, тоді як кожна кнопка керує тим же екземпляром Переглядача:
<nav id="toolbar" aria-label="Document viewer controls">
<button type="button" onclick="objViewer.GotoPage(1)">First</button>
<button type="button" onclick="objViewer.Next(false)">Previous</button>
<button type="button" onclick="objViewer.Next(true)">Next</button>
<button type="button" onclick="objViewer.GotoPage(objViewer.TotalPages())">Last</button>
<button type="button" onclick="objViewer.Zoom(false)">Zoom out</button>
<button type="button" onclick="objViewer.Zoom(true)">Zoom in</button>
<button type="button" onclick="objViewer.FitType('width')">Fit width</button>
<button type="button" onclick="objViewer.FitType('height')">Fit height</button>
<button type="button" id="openSearch">Search</button>
<button type="button" id="openAnnotations">Annotations</button>
</nav>Повна довідкова панель інструментів також копіює wwwroot/js/viewerToolbar.js у хост-застосунок для повороту, мініатюр, друку, повноекранного режиму, макету та допоміжних функцій стану кнопок. Завантажте цей хост-файл після Viewer.ReferenceScripts(...). Тримайте допоміжний файл і його <nav id="toolbar"> розмітку разом при копіюванні повної демонстраційної реалізації.
Дотримуйтесь порядку ініціалізації пакету, що використовується в обох довідкових застосунках:
- Вивести CSS для Переглядача та ліцензованих модулів.
- Відобразити панель інструментів Переглядача, монтування пошуку/анотацій та монтування Переглядача разом.
- Вивести скрипти для Переглядача та ліцензованих модулів.
- Завантажити
viewerToolbar.jsхост-застосунку. - Ініціалізувати
docViewerі зберегти отриманийobjViewer. - Ініціалізувати кожну ліцензовану стрічку пошуку або анотацій.
- Викликати
attach(objViewer)на кожній стрічці. - Відкрити документ і зберегти його токен для запитів Переглядача та модулів.
Doconut.TestApp.Distributed зберігає цю точну композицію інтерфейсу та той самий допоміжний елемент панелі інструментів Переглядача. Його додаткове значення запиту access та налаштування повторних спроб асинхронного рендерингу належать до розподіленого транспорту; вони не змінюють спосіб складання Переглядача, панелі інструментів або стрічок.
Захисні механізми на боці сервера важливі: коли опціональна можливість недоступна, її скрипт не виводиться, тому функція плагіна jQuery не існує.
<script>
let currentToken = '';
const refitViewer = () =>
requestAnimationFrame(() => objViewer.Refit());
@if (Viewer.IsSearchEnabled)
{
<text>
searchBar = $('#searchBarMount').doconutSearchBar({
docId: 'ctlDoc',
getRequestParams: () => ({ token: currentToken }),
onLayout: refitViewer
});
searchBar.attach(objViewer);
</text>
}
@if (Viewer.IsAnnotationEnabled)
{
<text>
annBar = $('#annBarMount').doconutAnnotationBar({
docId: 'ctlDoc',
getRequestParams: () => ({ token: currentToken }),
onLayout: refitViewer
});
annBar.attach(objViewer);
</text>
}
document.getElementById('openSearch').addEventListener('click', () => {
if (!searchBar) return;
searchBar.isOpen() ? searchBar.close() : searchBar.open();
});
document.getElementById('openAnnotations').addEventListener('click', () => {
if (!annBar) return;
annBar.isOpen() ? annBar.close() : annBar.open();
});
</script>Обидва вбудовані компоненти генерують власний DOM стрічки. Пошук містить групи «Знайти», «Параметри» та «Результати». Анотації містять інструменти створення, керування стилем, дії збереження та опціональні дії експорту/зображення. Панелі відкривають open(), close(), reset() та isOpen(); завжди викликайте attach(objViewer) один раз після їх створення.
У наведеному вище прикладі пропущено опціональні зворотні виклики хоста та кінцеві точки експорту/зображення анотацій, щоб мінімізувати запуск. Дивіться Пошук та Анотації для повного налаштування конкретних функцій, або Користувацькі теми, щоб стилізувати або замінити панель інструментів Переглядача, що належить хосту.
Відкрити документ
Серверна сторона — це один кінцевий пункт: інжектований сервіс Viewer відкриває документ і повертає токен сесії.
app.MapPost("/api/open", async (Viewer viewer) =>
{
// Токен є непрозорим — передайте його віджету, ніколи не журналюйте і не зберігайте його.
string token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
return Results.Ok(new { token });
});Клієнт отримує цей токен і передає його віджету за допомогою objViewer.View(token):
fetch('/api/open', { method: 'POST' })
.then(resp => resp.json())
.then(data => {
currentToken = data.token;
objViewer.View(currentToken);
});Закрити документ
Викличте objViewer.Close(), коли користувач залишає переглядач або відкриває замінний документ. У серверно‑орієнтованих робочих процесах, viewer.CloseDocument(token) негайно видаляє кешовану сесію, звільняє рушій рендерингу, стирає його маркер безпеки та анулює токен. Поступове закінчення терміну дії зрештою виконує те ж очищення, проте явне закриття рекомендовано для великих документів.
Повний потік запиту виглядає так:
AddDoconut + middleware
-> render CSS/scripts and mount div
-> initialize docViewer
-> OpenDocumentAsync
-> return opaque token
-> objViewer.View(token)
-> page/search/annotation requests
-> Close / CloseDocumentТримайте токен як облікові дані типу bearer: ніколи не журналюйте його, не зберігайте, передавайте лише віджету. Він ідентифікує активну сесію документа на сервері і перестає працювати, коли ця сесія закінчується — повторно відкрийте документ, щоб отримати новий токен.
Запустити
Помістіть PDF за адресою wwwroot/files/Sample.pdf, запустіть dotnet run і відкрийте сторінку, яка містить віджет. Перша сторінка відображається у переглядачі, з панеллю мініатюр зліва. Якщо цього не відбувається, дивіться Усунення проблем.
Що ви отримуєте без ліцензії
Відсутність ліцензії не викликає помилок. Переглядач відображає документ звичайно, але кожна сторінка містить водяний знак оцінки. Дивіться Налаштування ліцензії, щоб дізнатися, як Doconut знаходить ліцензію і які зміни відбуваються після її отримання.
Чи була ця сторінка корисною?