دليل: فتح المستندات باستخدام عارض Doconut المدمج في .NET 8
← Back to Blog4 min read

دليل: فتح المستندات باستخدام عارض Doconut المدمج في .NET 8

المقدمة

قد تُنشئ الأمثلة القديمة لـ 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)حقن Viewer بعد AddDoconut()
استدعاءات تحميل الترخيص الثابتة في كود الطلبتكوين إدخال الترخيص في AddDoconut()
أمثلة OpenDocument(...) المتزامنةاستخدام OpenDocumentAsync(...)
شبكة توصيل محتوى (CDN) للعارض خارجية أو مخترعةإصدار الموارد المدمجة باستخدام ReferenceCss وReferenceScripts
واجهة برمجة تطبيقات JavaScript العامة init()تهيئة $('#div_ctlDoc').docViewer(...)
تخزين رمز العارضاحتفظ بمعرف المستند الخاص بك؛ عامل الرمز كعنصر مؤقت

استخدم توثيق Doconut الرسمي وتحقق من الأمثلة مقابل إصدار الحزمة المثبت قبل تعديلها لتناسب كود الإنتاج.

#Doconut#.NET 8#Document Viewer#ASP.NET Core#JavaScript#عارض المستندات