
チュートリアル: .NET 8 で注入された Doconut ビューアでドキュメントを開く
はじめに
古い Doconut の例では、Viewer をキャッシュ、HTTP コンテキスト、ライセンスパスの引数で直接構築することがありますが、これは現在の .NET 8 統合モデルではありません。AddDoconut() は依存性注入で Viewer を登録し、アプリケーションのエンドポイントはコンストラクタを呼び出す代わりにサービスを受け取ります。

このチュートリアルは現在のリクエストフローに従います:サービスとミドルウェアを登録し、埋め込みビューアリソースを出力し、OpenDocumentAsync でドキュメントを開き、不透明なセッショントークンを返し、そのトークンをブラウザウィジェットに渡します。
1. Doconut のインストールと登録
.NET 8 パッケージを追加します:
dotnet add package Doconut.NET8
Doconut と ASP.NET セッションサービスを登録します:
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.MiddlewarePath = "/doconut";
options.ResourcesPath = "/doconut-res";
options.UnsafeMode = false;
});
builder.Services.AddSession();
必要な順序でミドルウェアを接続します。リソースミドルウェアは最終的なドキュメントミドルウェアの前に実行される必要があります:
app.UseRouting();
app.UseSession();
app.UseDoconutResources();
app.Map("/doconut", branch => branch.UseDoconut());
MiddlewarePath は設定を調整しますが、単体で ASP.NET のブランチを作成するわけではありません。マッピングされた /doconut パスはウィジェットの BasePath と一致する必要があります。
2. ビューアのサーフェスとリソースを追加
Doconut ブラウザビューアは jQuery プラグインです。Razor ページで Viewer を注入し、依存関係の順序でリソースタグを出力させます:
@inject Doconut.Viewer Viewer
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
IncludeViewerCss = true
}))
@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
IncludeJQuery = true,
IncludeViewerScripts = true
}))
<div id="divDocViewer">
<div id="div_ctlDoc"></div>
</div>
サーバー登録と一致するパスでウィジェットを初期化します:
const objViewer = $('#div_ctlDoc').docViewer({
showThumbs: true,
autoLoad: false,
pageZoom: 100,
FitType: 'width',
BasePath: '/doconut',
ResPath: '/doconut-res/images',
onError: function (message) {
console.error('Doconut viewer error:', message);
}
});
オプションの大文字小文字は重要です。インストールされたバージョンが示す名前を使用し、単一のスタイルに正規化しないでください。
3. Viewer を注入してドキュメントを開く
Viewer はトランジェントサービスとして登録されています。エンドポイント注入、コンストラクタ注入、または ASP.NET Core アプリケーションで利用できる同等の手段で解決します。
app.MapPost("/api/open", async (
Viewer viewer,
CancellationToken ct) =>
{
string token = await viewer.OpenDocumentAsync(
"wwwroot/files/Sample.pdf",
ct: ct);
return Results.Ok(new { token });
});
アップロードの場合は、ストリームと拡張子でフォーマットを識別できる FileInfo を提供します:
app.MapPost("/api/open-upload", async (
IFormFile file,
Viewer viewer,
CancellationToken ct) =>
{
await using var stream = file.OpenReadStream();
string token = await viewer.OpenDocumentAsync(
stream,
new FileInfo(file.FileName),
ct: ct);
return Results.Ok(new { token });
});
アップロードサイズ、拡張子、認可を検証してからユーザー提供コンテンツを開いてください。送信されたファイル名をサーバーパスに変換しないでください。
4. トークンをウィジェットに渡す
オープンエンドポイントを取得し、返されたトークンを objViewer.View に渡します:
fetch('/api/open', { method: 'POST' })
.then(response => {
if (!response.ok) throw new Error('The document could not be opened.');
return response.json();
})
.then(data => objViewer.View(data.token))
.catch(error => console.error(error));
トークンはライブドキュメントセッションのベアラークレデンシャルとして扱います:
- トークンをログに記録したり永続化したりしないでください。
- 認可されたクライアントにのみ返却してください。
- ソースファイルのパスを公開しないでください。
- セッションが期限切れになったらドキュメントを再度開いてください。
- ドキュメントが不要になったらセッションを閉じてください。
5. サーバー側セッションを意図的に閉じる
クライアントコードはユーザーがビューアを離れたときに objViewer.Close() を呼び出すことができます。サーバー側のワークフローでも既知のトークンを明示的に取り消すことができます:
app.MapPost("/api/close", (string token, Viewer viewer) =>
{
viewer.CloseDocument(token);
return Results.NoContent();
});
明示的なクローズは特に大きなドキュメントで有用です。セッションの期限切れはフォールバックとして残り、予測可能なアプリケーションライフサイクル管理の代替にはなりません。
6. コアが動作したらオプションモジュールを追加
検索と注釈は同じ初期化されたビューアに付随します。ベースフローが成功した後に、CSS、スクリプト、マウント、ライセンスチェック、ライフサイクルコールバックを追加してください:
AddDoconut + session services
-> UseSession
-> UseDoconutResources
-> mapped UseDoconut branch
-> viewer resources and mount
-> initialize docViewer
-> OpenDocumentAsync
-> objViewer.View(token)
この順序により、コアのレンダリング失敗とオプションモジュールの設定が分離されます。
一般的な移行ミス
| 古いまたは誤ったパターン | 現在の .NET 8 の方向性 |
|---|---|
new Viewer(cache, accessor, licensePath) | AddDoconut() 後に Viewer を注入 |
| リクエストコード内での静的ライセンスロード呼び出し | AddDoconut() でライセンス入力を構成 |
同期的な OpenDocument(...) の例 | OpenDocumentAsync(...) を使用 |
| 外部または独自のビューア CDN | ReferenceCss と ReferenceScripts で埋め込みリソースを出力 |
汎用的な JavaScript init() API | $('#div_ctlDoc').docViewer(...) で初期化 |
| ビューアトークンを永続化 | ドキュメント ID を永続化し、トークンは一時的に扱う |
公式の Doconut ドキュメント を使用し、実装前にインストールされたパッケージバージョンに対して例を検証してください。