
Tutorial: Membuka Dokumen dengan Viewer Doconut yang Disuntikkan di .NET 8
Pendahuluan
Contoh Doconut yang lebih lama mungkin membangun Viewer secara langsung dengan argumen cache, HTTP-context, dan license-path. Itu bukan model integrasi .NET 8 yang saat ini. AddDoconut() mendaftarkan Viewer dengan dependency injection, dan endpoint aplikasi menerima layanan tersebut alih‑alih memanggil konstruktor.

Tutorial ini mengikuti alur permintaan saat ini: daftarkan layanan dan middleware, hasilkan sumber daya viewer yang tersemat, buka dokumen dengan OpenDocumentAsync, kembalikan token sesi tak transparan, dan kirim token tersebut ke widget browser.
1. Instal dan daftarkan Doconut
Tambahkan paket .NET 8:
dotnet add package Doconut.NET8
Daftarkan Doconut dan layanan sesi ASP.NET:
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.MiddlewarePath = "/doconut";
options.ResourcesPath = "/doconut-res";
options.UnsafeMode = false;
});
builder.Services.AddSession();
Hubungkan middleware dalam urutan yang diperlukan. Middleware sumber daya harus dijalankan sebelum middleware dokumen terminal:
app.UseRouting();
app.UseSession();
app.UseDoconutResources();
app.Map("/doconut", branch => branch.UseDoconut());
MiddlewarePath mengkoordinasikan konfigurasi tetapi tidak membuat cabang ASP.NET secara otomatis. Jalur /doconut yang dipetakan harus cocok dengan BasePath widget.
2. Tambahkan permukaan penampil dan sumber daya
Viewer browser Doconut adalah plugin jQuery. Pada halaman Razor, suntikkan Viewer dan minta ia menghasilkan tag sumber daya dalam urutan dependensi:
@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>
Inisialisasi widget dengan jalur yang cocok dengan pendaftaran server:
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);
}
});
Penulisan opsi bersifat sensitif. Gunakan nama yang ditampilkan oleh versi yang terpasang alih‑alih menormalkannya ke satu gaya.
3. Suntikkan Viewer dan buka dokumen
Viewer didaftarkan sebagai layanan transient. Resolusi dapat dilakukan melalui injeksi endpoint, injeksi konstruktor, atau fasilitas setara dalam aplikasi ASP.NET Core Anda.
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 });
});
Untuk unggahan, berikan aliran dan FileInfo yang ekstensi‑nya mengidentifikasi format sumber:
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 });
});
Validasi ukuran unggahan, ekstensi, dan otorisasi sebelum membuka konten yang diberikan pengguna. Jangan ubah nama file yang dikirim menjadi jalur server.
4. Kirim token ke widget
Ambil endpoint buka dan serahkan token yang dikembalikan ke 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));
Perlakukan token sebagai kredensial bearer untuk sesi dokumen yang hidup:
- Jangan mencatat atau menyimpannya.
- Kembalikan hanya ke klien yang berwenang.
- Jangan mengungkapkan jalur file sumber.
- Buka kembali dokumen ketika sesi kedaluwarsa.
- Tutup sesi ketika dokumen tidak lagi diperlukan.
5. Tutup sesi sisi server secara sengaja
Kode klien dapat memanggil objViewer.Close() ketika pengguna meninggalkan penampil. Alur kerja server juga dapat mencabut token yang diketahui secara eksplisit:
app.MapPost("/api/close", (string token, Viewer viewer) =>
{
viewer.CloseDocument(token);
return Results.NoContent();
});
Penutupan eksplisit sangat berguna untuk dokumen berukuran besar. Kedaluwarsa sesi tetap menjadi cadangan, bukan pengganti manajemen siklus hidup aplikasi yang dapat diprediksi.
6. Tambahkan modul opsional hanya setelah inti berfungsi
Pencarian dan anotasi menempel pada viewer yang sama sudah diinisialisasi. Tambahkan CSS, skrip, mount, pemeriksaan lisensi, dan callback siklus hidup hanya setelah alur dasar berhasil:
AddDoconut + session services
-> UseSession
-> UseDoconutResources
-> mapped UseDoconut branch
-> viewer resources and mount
-> initialize docViewer
-> OpenDocumentAsync
-> objViewer.View(token)
Urutan ini memisahkan kegagalan rendering inti dari konfigurasi modul opsional.
Kesalahan migrasi umum
| Pola lama atau tidak tepat | Arah .NET 8 saat ini |
|---|---|
new Viewer(cache, accessor, licensePath) | Suntikkan Viewer setelah AddDoconut() |
| Panggilan pemuatan lisensi statis dalam kode permintaan | Konfigurasikan masukan lisensi di AddDoconut() |
Contoh OpenDocument(...) sinkron | Gunakan OpenDocumentAsync(...) |
| CDN viewer eksternal atau buatan | Hasilkan sumber daya tersemat dengan ReferenceCss dan ReferenceScripts |
API JavaScript generik init() | Inisialisasi $('#div_ctlDoc').docViewer(...) |
| Menyimpan token viewer | Simpan ID dokumen Anda; perlakukan token sebagai sementara |
Gunakan dokumentasi Doconut resmi dan verifikasi contoh terhadap versi paket yang terpasang sebelum menyesuaikannya ke kode produksi.