
Tutorial: Membuka Dokumen dengan Doconut Viewer yang Disuntikkan di .NET 8
Pendahuluan
Contoh Doconut yang lebih lama mungkin membuat Viewer secara langsung dengan argumen cache, konteks HTTP, dan jalur lisensi. Itu bukan model integrasi .NET 8 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 penampil yang tersemat, buka dokumen dengan OpenDocumentAsync, kembalikan token sesi yang tidak dapat dibaca, dan kirim token tersebut ke widget browser.
1. Instal dan daftarkan Doconut
Tambahkan paket .NET 8:
dotnet add package Doconut.NET8
Daftarkan layanan Doconut dan 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
Doconut browser viewer adalah plugin jQuery. Pada halaman Razor, suntikkan Viewer dan minta agar ia menghasilkan tag sumber daya dalam urutan ketergantungan:
@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 huruf pada opsi bersifat penting. Gunakan nama yang ditampilkan oleh versi yang diinstal alih-alih menormalkannya menjadi satu gaya.
3. Suntikkan Viewer dan buka dokumen
Viewer terdaftar sebagai layanan transient. Resolusikan 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, sediakan stream 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 mengubah 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 langsung:
- Jangan log atau simpan token tersebut.
- Kembalikan hanya kepada klien yang berwenang.
- Jangan mengungkapkan jalur file sumber.
- Buka kembali dokumen ketika sesi berakhir.
- 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 melekat pada penampil yang sama yang telah diinisialisasi. Tambahkan CSS, skrip, mount, pemeriksaan lisensi, dan callback siklus hidup mereka 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 salah | Arah .NET 8 saat ini |
|---|---|
new Viewer(cache, accessor, licensePath) | Suntikkan Viewer setelah AddDoconut() |
| Pemanggilan pemuatan lisensi statis dalam kode permintaan | Konfigurasikan input lisensi di AddDoconut() |
Contoh OpenDocument(...) sinkron | Gunakan OpenDocumentAsync(...) |
| CDN penampil eksternal atau buatan | Emit sumber daya tersemat dengan ReferenceCss dan ReferenceScripts |
API init() JavaScript generik | Inisialisasi $('#div_ctlDoc').docViewer(...) |
| Menyimpan token penampil | Simpan ID dokumen Anda; perlakukan token sebagai sementara |
Gunakan dokumentasi Doconut resmi dan verifikasi contoh terhadap versi paket yang diinstal sebelum menyesuaikannya ke kode produksi.