Швидкий старт
Відобразіть ваш перший документ за кілька хвилин
Цей посібник переводить застосунок ASP.NET Core від порожнього Program.cs до документа, що відображається у браузері: реєстрація сервера, повний пакет Viewer (панель інструментів Viewer, монтування Viewer та додаткові стрічки Пошуку/Анотації), посилання на ресурси, ініціалізація клієнта, відкриття документа та виконання.
Налаштування сервера
AddDoconut() реєструє сервіси; UseDoconutResources() і UseDoconut() підключають middleware. Виклик ресурсів має бути першим. Виклики сесії також потрібні — стандартна безпека документів Doconut перевіряє кожен запит сторінки проти стану сесії ASP.NET. Стан сесії потребує кешу: AddDistributedMemoryCache() забезпечує його. Додаток MVC або Razor Pages вже реєструє його, але додаток minimal-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();Для розташування шляхів у виробничому стилі, прив'яжіть middleware документа до явної гілки та збережіть узгодженість чотирьох налаштувань шляхів:
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'. Запишіть обидва без початкового слешу: viewer додає його сам, тому '/doconut' стане //doconut/DocImage.axd, що браузер сприймає як запит до хоста з назвою doconut, і viewer завершує роботу з помилкою "The viewer handler could not be reached".
Додайте viewer на сторінку
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">
<!-- Кнопки навігації, масштабування, пошуку та анотацій переглядача -->
</nav>
<div id="searchBarMount"></div>
<div id="annBarMount"></div>
<div id="divDocViewer">
<div id="div_ctlDoc"></div>
</div>Посилання на ресурси viewer
У Razor‑виді, інжектований сервіс Viewer генерує теги <link> та <script> viewer у порядку залежностей — віджет є плагіном jQuery, тому jQuery має бути завантажений перед скриптами viewer:
@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. Немає послідовного правила; якщо регістр вказано неправильно, параметр буде без повідомлення проігноровано (віджет повернеться до значення за замовчуванням замість викидання помилки).
Зібрати повний пакет Viewer
Обидві довідкові програми .NET 8 встановлюють наступні частини разом на одній сторінці:
| Частина пакету | Вимога | Як підключено |
|---|---|---|
Ресурси Viewer, монтування та objViewer | Обов’язково | Основний рендерер документу |
| Панель інструментів Viewer | Обов’язково у довідковій композиції | Розмітка хоста; кнопки викликають той самий objViewer |
| Пошукова панель | Опціональний, ліцензований модуль | doconutSearchBar(...).attach(objViewer) |
| Панель анотацій | Опціональний, ліцензований модуль | doconutAnnotationBar(...).attach(objViewer) |
Хоча основна панель інструментів Viewer є розміткою хоста, вона встановлюється разом з Viewer і ніколи не повинна документуватись як окремий елемент управління. Це зберігає її макет, мітки, іконки та правила авторизації під контролем вашого застосунку, при цьому кожна кнопка керує тим же екземпляром Viewer:
<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"> розмітку разом під час копіювання повної демонстраційної реалізації.
Дотримуйтесь порядку ініціалізації пакету, що використовується в обох довідкових застосунках:
- Вивести ресурси Viewer, Search та Annotation разом.
- Відобразити панель інструментів Viewer, монтування Ribbon та монтування Viewer разом.
- Спочатку ініціалізувати
docViewer. - Створити кожен ліцензований Ribbon і приєднати його до того ж
objViewer. - Відкрити документ і зберегти його токен для запитів модуля.
Doconut.TestApp.Distributed зберігає цю точну композицію UI та той самий допоміжний модуль панелі інструментів Viewer. Його додаткове значення запиту access та налаштування повторних спроб асинхронного рендерингу належать до розподіленого транспорту; вони не змінюють спосіб складання Viewer, панелі інструментів або Ribbon-ів.
Захисні механізми на сервері важливі: коли опціональна можливість недоступна, її скрипт не виводиться, тому функція 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 Ribbon. Search містить групи Find, Options та Results. Annotation містить інструменти створення, елементи керування стилем, дії збереження та опціональні дії експорту/зображення. Панелі надають open(), close(), reset() та isOpen(); завжди викликайте attach(objViewer) один раз після їх створення.
У наведеному вище прикладі пропущено опціональні зворотні виклики хоста та кінцеві точки експорту/зображення Annotation, щоб мінімізувати запуск. Дивіться Пошук та Анотації для повної налаштування конкретних функцій, або Користувацькі теми щоб стилізувати або замінити панель інструментів Viewer, що належить хосту.
Відкрити документ
Серверна сторона має один кінцевий пункт: інжектований сервіс 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Ставтеся до токену як до облікових даних носія: ніколи не реєструйте його, ніколи не зберігайте, передавайте його лише віджету. Він ідентифікує активну сесію документа на сервері і перестає працювати, коли ця сесія закінчується — повторно відкрийте документ, щоб отримати новий.
Запустити
Розмістіть PDF за адресою wwwroot/files/Sample.pdf, запустіть dotnet run і відкрийте сторінку, що містить віджет. Перша сторінка відображається у переглядачі з панеллю мініатюр ліворуч. Якщо цього не відбувається, дивіться Усунення проблем.
Що ви отримуєте без ліцензії
Відсутність ліцензії не викликає помилок. Переглядач відображає документ у звичайному режимі, проте кожна сторінка містить водяний знак оцінки. Дивіться Налаштування ліцензії, щоб дізнатися, як Doconut знаходить ліцензію і які зміни відбуваються після її виявлення.
Чи була ця сторінка корисною?