Blazor Server و WebAssembly
العرض يتم على الخادم في كلتا الحالتين. في Server يكون الاستدعاء مباشرًا؛ في WebAssembly تقوم بفتح الاستدعاء كنقطة نهاية API بسيطة وتمنح الرمز المميز المُرجع إلى الأداة. كلاهما يتطلب بضع أسطر.
يمنحك Blazor نموذج مكوّنات وحلقة عرض لا تهتم كثيرًا بجافاسكريبت من طرف ثالث. Doconut يعمل مع ذلك بدلاً من ضدّه: يحدث العرض على الخادم في عمليتك الخاصة، وتثبت الأداة في عنصر بسيط تتحكم فيه عبر دورة حياة التفاعل العادية.
المشكلة
يعني المسار من جانب العميل شحن محرك عرض إلى المتصفح. في Blazor WebAssembly يضيف ذلك مباشرة إلى حجم التنزيل الخاص بك، وهو يغطي فقط PDF — في اللحظة التي يرفع فيها أحدهم ملف DOCX أو XLSX تعود إلى الصفر.
يعني مسار iframe-to-Office أن مستنداتك تمر عبر بنية تحتية لشخص آخر، وهو نقاش مع فريق الأمان قد لا ترغب في إجرائه مرتين.
يتبع Doconut المسار الثالث. يتم تحويل الملف إلى صور صفحات بواسطة خادمك الخاص، ولا يحتاج Blazor سوى إلى استضافة div. شجرة المكوّنات الخاصة بك لا تعيد عرض عارض لا تملكه أبدًا، ولا توجد أي صراعات في محرك الفروقات.
القدرات
العرض يتم على الخادم في كلتا الحالتين. في Server يكون الاستدعاء مباشرًا؛ في WebAssembly تقوم بفتح الاستدعاء كنقطة نهاية API بسيطة وتمنح الرمز المميز المُرجع إلى الأداة. كلاهما يتطلب بضع أسطر.
قم بتهيئة الأداة مرة واحدة، بعد أول عرض، عبر ربط التفاعل JS القياسي. لأن Blazor لا يملك DOM الداخلي للعارض، فإن عمليات العرض اللاحقة تتركه دون تغيير.
Interactive Server، Interactive WebAssembly، أو Auto. يتم تشغيل العارض برمز مميز غير شفاف بدلاً من حالة المكوّن، لذا لا يغيّر تبديل وضع العرض التكامل.
يفتح نفس المكوّن ملفات PDF و DOCX و XLSX و PPTX و DWG و MSG وبقية الكتالوج. تكتب صفحة عارض واحدة، لا واحدة لكل عائلة ملفات.
واجهة التنقل تأتي مع الأداة. أنت تقوم بربط عارض، لا بناء واحد من لوحة قماش وإدخال رقم الصفحة.
لا يتم بث أي شيء إلى المتصفح سوى صور الصفحات المُعالجة، وهذا أمر مهم أكثر في WebAssembly مما يتوقع الناس — فالعميل، في النهاية، قابل للفحص بالكامل.
التكامل
doconutHost.mount هو بضع أسطر من جافاسكريبت الخاص بك التي تستدعي $('#div_ctlDoc').docViewer({ ... }) ثم .View(token). إبقاءه خارج Blazor هو مقصود — يجب ألا يكون DOM الخاص بالأداة شيئًا يحاول العارض التوفيق معه.
المنصات المدعومة
// Program.cs — order matters
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
});
builder.Services.AddSession();
app.UseSession(); // before UseDoconut()
app.UseDoconutResources(); // before UseDoconut()
app.UseDoconut();
// Viewer.razor — open server-side, hand the token to the widget
@inject Doconut.Viewer Viewer
@inject IJSRuntime JS
<div id="divDocViewer"><div id="div_ctlDoc"></div></div>
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
// Authorize first — the viewer renders whatever you hand it.
string token = await Viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
await JS.InvokeVoidAsync("doconutHost.mount", token);
}
}التفاصيل
كلاهما. يحدث العرض دائمًا على الخادم، لذا في WebAssembly تضيف نقطة نهاية واحدة تستدعي OpenDocumentAsync وتُرجع الرمز المميز. العميل لا يحلل أي مستند، وهذا هو السبب بالضبط في بقاء حمولة WASM دون تغيير.
لا، بشرط أن تثبت في عنصر يعتبره Blazor ورقة. عرض div فارغ ودع الأداة تملأه عبر التفاعل — لا يوجد أطفال لمحرك الفروقات لتوفيقهم.
لا. صفحة واحدة تتعامل مع كامل الكتالوج. يتم اكتشاف الصيغة من المستند الذي تفتحه، وليس ما تختاره مسبقًا.
رخصة مؤقتة تستغرق بضع دقائق لطلبها وتعمل بالكامل على جهازك الخاص. الملفات المهمة هي تلك التي تُعطِّل عارضك الحالي بالفعل.