Hızlı Başlangıç
İlk belgenizi dakikalar içinde render edin
Bu rehber, boş bir Program.cs dosyasından tarayıcıda render edilen bir belgeye kadar bir ASP.NET Core uygulamasını adım adım gösterir: sunucu kaydı, tam Viewer paketi (Viewer araç çubuğu, Viewer montajı ve isteğe bağlı Arama/Notasyon şeritleri), varlık referansları, istemci başlatma, belge açma ve yürütme.
Sunucu kurulumu
AddDoconut() hizmetleri kaydeder; UseDoconutResources() ve UseDoconut() ara katmanı bağlar. Kaynak çağrısı önce gelmelidir. Oturum çağrıları da gereklidir — Doconut'un varsayılan belge güvenliği her sayfa isteğini ASP.NET oturum durumuna karşı doğrular. Oturum durumu bir önbellek gerektirir: AddDistributedMemoryCache() bir tane sağlar. Bir MVC veya Razor Pages uygulaması zaten bunu kaydeder, ancak minimal-API uygulaması kaydetmez ve bu olmadan uygulama Unable to resolve service for type 'IDistributedCache' hatasıyla başlatmada durur. Daha önce Kurulum sırasında Doconut kaydettiniz mi? Bir sonraki bölüme atlayın.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // oturum durumu bir önbellek gerektirir (MVC/Razor Pages zaten ekler)
builder.Services.AddSession(); // Doconut belge güvenliği ASP.NET oturum durumuna dayanır
app.UseSession(); // UseDoconut()'dan önce UseSession() çağırın
app.UseDoconutResources(); // UseDoconut()'dan önce kaydedilmelidir
app.UseDoconut();Üretim tarzı bir yol düzeni için, belge ara katmanını açık bir dala eşleyin ve dört yol ayarını hizalı tutun:
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 bir koordinasyon değeridir; tek başına bir ASP.NET Core dalını eşlemez. Bu örnekte host /doconut yolunu eşler, bu yüzden istemci BasePath: 'doconut' kullanır. ResourcesPath gömülü paketi /doconut-res adresinde sunar ve widget'ın resim kaynağı yolu bu nedenle ResPath: 'doconut-res/images' olur. İkisini de başında eğik çizgi olmadan yazın: görüntüleyici kendisi bir tane ekler, bu yüzden '/doconut' //doconut/DocImage.axd haline gelir ve tarayıcı bunu doconut adlı bir ana bilgisayara istek olarak yorumlar, bu da görüntüleyicinin "The viewer handler could not be reached" hatasıyla başarısız olmasına neden olur.
Görüntüleyiciyi bir sayfaya ekleyin
Viewer, sayfanın gerekli çekirdeğidir. Render yüzeyi iki iç içe div kullanır:
<div id="divDocViewer">
<div id="div_ctlDoc"></div>
</div>Araç çubuğu, modül montajları ve Viewer yüzeyini tek bir sayfa kompozisyonu olarak ele alın. Arama ve Notasyon, gömülü şeritlerini isteğe bağlı montajlara enjekte eder, ancak bu modüller asla bağımsız değildir: her zaman aynı sayfadaki Viewer'a bağlanırlar. Doconut.TestApp ve Doconut.TestApp.Distributed ile aynı sırayı kullanın:
<nav id="toolbar" aria-label="Document viewer controls">
<!-- Viewer navigation, zoom, Search, and Annotation buttons -->
</nav>
<div id="searchBarMount"></div>
<div id="annBarMount"></div>
<div id="divDocViewer">
<div id="div_ctlDoc"></div>
</div>Görüntüleyici varlıklarını referans gösterin
Bir Razor görünümünde, enjekte edilen Viewer servisi, bağımlılık sırasına göre viewer'ın <link> ve <script> etiketlerini üretir — widget bir jQuery eklentisidir, bu yüzden jQuery viewer script'lerinden önce yüklenmelidir:
@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
}))Tam Viewer paketi için, Viewer ve modül kaynaklarını birlikte isteyin:
@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 ve IncludeViewerScripts zorunlu çekirdek bayraklardır. Bunlar, Viewer montajı ve bir docViewer örneği olmadan bir Arama veya Notasyon Şeridi örneği asla yayınlamayın. ReferenceCss ve ReferenceScripts, mevcut lisans bu yeteneği vermiyorsa isteğe bağlı bir modülün kaynaklarını atlar; çekirdek Viewer yine de başlar.
Viewer'ı Başlatma
İstemci tarafı widget'ı bir jQuery eklentisidir. Bu, gerçek başlatma seçeneklerinin minimal bir setidir (sözde kod değildir):
let searchBar = null;
let annBar = null;
const objViewer = $('#div_ctlDoc').docViewer({
showThumbs: true,
autoLoad: false,
pageZoom: 100,
FitType: 'width',
BasePath: 'doconut', // başında '/' yok
ResPath: 'doconut-res/images', // başında '/' yok
onViewerReady: function () {
// sayfalar görünür; burada bir yükleme göstergesini gizlemek güvenli
},
// Gömülü şerit mevcut olduğunda ek açıklama yaşam döngüsü olaylarını yönlendir.
onAnnLoaded: () => annBar?.handleAnnLoaded(),
onAnnSaved: () => annBar?.handleAnnSaved(),
onAnnSaveError: () => annBar?.handleAnnSaveError(),
onAnnClosed: () => annBar?.handleAnnClosed(),
onError: function (message) {
console.error('Doconut viewer error:', message);
}
});Seçenek adlandırması gerçekten karışıktır — showThumbs, autoLoad ve pageZoom camelCase iken, FitType, BasePath ve ResPath PascalCase'dir. Tutarlı bir kural yoktur; büyük/küçük harf uyumunu yanlış yaparsanız seçenek sessizce yok sayılır (widget, hata fırlatmak yerine varsayılanına geri döner).
Tam Viewer Paketi Oluşturma
Her iki .NET 8 referans uygulaması da aşağıdaki parçaları tek bir sayfada birlikte kurar:
| Paketin parçası | Gereksinim | Nasıl bağlanır |
|---|---|---|
Viewer kaynakları, bağlama ve objViewer | Gerekli | Çekirdek belge renderleyicisi |
| Viewer araç çubuğu | Referans bileşeninde gerekli | Ana işaretleme; düğmeler aynı objViewer'ı çağırır |
| Arama şeridi | Opsiyonel, lisanslı modül | doconutSearchBar(...).attach(objViewer) |
| Açıklama şeridi | Opsiyonel, lisanslı modül | doconutAnnotationBar(...).attach(objViewer) |
Ana Viewer araç çubuğu ana işaretleme olmasına rağmen, Viewer ile birlikte kurulur ve asla izole bir kontrol olarak belgelenmemelidir. Bu, düzenini, etiketlerini, simgelerini ve yetkilendirme kurallarını uygulamanızın kontrolü altında tutar ve her düğme aynı Viewer örneğini çalıştırır:
<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>Tam referans araç çubuğu ayrıca wwwroot/js/viewerToolbar.js dosyasını döndürme, küçük resim, yazdırma, tam ekran, düzen ve düğme durumu yardımcıları için ana uygulamaya kopyalar. Bu ana dosyayı Viewer.ReferenceScripts(...) sonrası yükleyin. Tam demo uygulamasını kopyalarken yardımcı programı ve onun <nav id="toolbar"> işaretlemesini birlikte tutun.
Her iki referans uygulamasında kullanılan paket başlatma sırasını koruyun:
- Viewer, Search ve Annotation kaynaklarını birlikte yayınlayın.
- Viewer araç çubuğunu, Ribbon bağlamalarını ve Viewer bağlamasını birlikte render edin.
docViewer'ı ilk olarak başlatın.- Her lisanslı Ribbon'ı oluşturun ve aynı
objViewer'a ekleyin. - Belgeyi açın ve modül istekleri için token'ını saklayın.
Doconut.TestApp.Distributed bu tam UI bileşimini ve aynı Viewer-araç çubuğu yardımcı programını korur. Ek access istek değeri ve eşzamanlı-render yeniden deneme ayarları dağıtılmış taşıma için özeldir; Viewer, araç çubuğu veya Ribbon'ların nasıl birleştirildiğini değiştirmez.
Sunucu tarafı korumaları önemlidir: opsiyonel bir yetenek mevcut olmadığında, onun script'i yayınlanmaz, bu yüzden jQuery eklenti fonksiyonu mevcut olmaz.
<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>Her iki gömülü bileşen de kendi Ribbon DOM'larını üretir. Search, Find, Options ve Results gruplarını içerir. Annotation, yazar araçlarını, stil kontrollerini, kaydetme eylemlerini ve opsiyonel dışa aktarım/görüntü eylemlerini içerir. Çubuklar open(), close(), reset() ve isOpen() metodlarını sunar; oluşturulduktan sonra her zaman bir kez attach(objViewer) çağırın.
Yukarıdaki örnek, başlangıcı minimal tutmak için opsiyonel ana geri çağırmaları ve Annotation dışa aktarım/görüntü uç noktalarını atlar. Tam özellik‑spesifik kurulumu görmek için Search, Annotations sayfalarına bakın veya ana‑sahibe ait Viewer araç çubuğunu stil vermek ya da değiştirmek için Custom Themes sayfasına göz atın.
Bir belge açın
Sunucu tarafı tek bir uç noktadır: enjekte edilen Viewer servisi belgeyi açar ve bir oturum belirteci döndürür.
app.MapPost("/api/open", async (Viewer viewer) =>
{
// Belirteç opaktır — widget'a verin, asla kaydetmeyin veya kalıcı hale getirmeyin.
string token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
return Results.Ok(new { token });
});İstemci bu belirteci alır ve objViewer.View(token) ile widget'a verir:
fetch('/api/open', { method: 'POST' })
.then(resp => resp.json())
.then(data => {
currentToken = data.token;
objViewer.View(currentToken);
});Belgeyi kapatın
objViewer.Close()'ı, kullanıcı görüntüleyiciden ayrıldığında veya yerine yeni bir belge açtığında çağırın. Sunucu yönelimli iş akışlarında, viewer.CloseDocument(token) önbellekteki oturumu hemen kaldırır, render motorunu serbest bırakır, güvenlik işaretçisini siler ve belirteci iptal eder. Kaydırmalı süresi dolma sonunda aynı temizlik işlemini yapar, ancak büyük belgeler için açıkça kapatılması önerilir.
Tamamlanmış istek akışı şu şekildedir:
AddDoconut + middleware
-> render CSS/scripts and mount div
-> initialize docViewer
-> OpenDocumentAsync
-> return opaque token
-> objViewer.View(token)
-> page/search/annotation requests
-> Close / CloseDocumentBelirteci bir taşıyıcı kimlik bilgisi gibi ele alın: asla kaydetmeyin, asla kalıcı hale getirmeyin, sadece widget'a verin. Sunucudaki canlı bir belge oturumunu tanımlar ve oturum süresi dolduğunda çalışmayı durdurur — yeni bir belirteç almak için belgeyi yeniden açın.
Çalıştırın
wwwroot/files/Sample.pdf konumuna bir PDF koyun, dotnet run komutunu çalıştırın ve widget'ı barındıran sayfayı açın. İlk sayfa görüntüleyicide, sol tarafta bir küçük resim paneliyle render edilir. Eğer render edilmezse, Sorun Giderme bölümüne bakın.
Lisans olmadan neler elde edersiniz
Eksik bir lisans hata vermez. Görüntüleyici normal şekilde render eder, ancak her sayfa bir değerlendirme filigranı taşır. Doconut'un bir lisans nasıl bulduğunu ve bulduktan sonra nelerin değiştiğini görmek için Lisans Kurulumu bölümüne bakın.
Bu sayfa yardımcı oldu mu?