مدير ملفات ASP.NET MVC مجاني مع عارض PDF مدمج
← Back to Blog••5 min read

مدير ملفات ASP.NET MVC مجاني مع عارض PDF مدمج

بناء مدير ملفات ASP.NET MVC مجاني يعرض ملفات PDF

تريد صفحة تُظهر قائمة الملفات المخزنة على الخادم، وتسمح للمستخدم بتحميلها أو حذفها، وتفتح أي ملف PDF داخل المتصفح دون مغادرة الموقع. يوضح الدليل التالي كيفية القيام بذلك باستخدام ASP.NET MVC العادي، وذاكرة الجلسة المدمجة، وعارض المستندات الشامل من Doconut.


1. إنشاء تطبيق MVC بسيط

أنشئ مشروع MVC جديد في Visual Studio (أي نسخة، بما فيها النسخة المجانية Community).

أضف FileController الذي سيستضيف إجراءات مدير الملفات:

public class FileController : Controller
{
    private readonly string _root = Path.Combine(Directory.GetCurrentDirectory(), "App_Data", "Docs");

    public IActionResult Index()
    {
        var files = Directory.GetFiles(_root).Select(Path.GetFileName).ToList();
        return View(files);
    }

    public IActionResult Download(string name)
    {
        var path = Path.Combine(_root, name);
        if (!System.IO.File.Exists(path)) return NotFound();
        var mime = "application/octet-stream";
        return PhysicalFile(path, mime, name);
    }

    public IActionResult Delete(string name)
    {
        var path = Path.Combine(_root, name);
        if (System.IO.File.Exists(path)) System.IO.File.Delete(path);
        return RedirectToAction(nameof(Index));
    }

    public async Task<IActionResult> ViewPdf(string name)
    {
        var path = Path.Combine(_root, name);
        if (!System.IO.File.Exists(path)) return NotFound();

        // يتم إنشاء رمز المشاهد هنا (انظر القسم 2)
        var token = await _viewer.OpenDocumentAsync(
            path,
            new Doconut.PdfConfig { AllowSearch = true },
            new DocOptions(),
            CancellationToken.None);

        ViewBag.Token = token;
        ViewBag.BasePath = "doconut";          // يتطابق مع فرع Middleware
        ViewBag.ResPath = "doconut-res/images";// الموارد المدمجة
        return View();
    }

    private readonly Doconut.Viewer _viewer;
    public FileController(Doconut.Viewer viewer) => _viewer = viewer;
}

المتحكم (Controller) يقوم بثلاث مهام:

  1. Index – يقرأ مجلد App_Data/Docs ويُمرّر أسماء الملفات إلى عرض (view).
  2. Download / Delete – إجراءات MVC قياسية تستخدم المساعد المدمج PhysicalFile.
  3. ViewPdf – يفتح ملف PDF المحدد باستخدام Doconut، يتلقى رمز أمان، ويُمرره إلى عرض Razor.

2. ربط حالة الجلسة وخدمات Doconut

يعتمد عارض Doconut على حالة جلسة ASP.NET لحماية الرمز الذي يحدد المستند. أضف الخدمات المطلوبة في Program.cs (أو Startup.cs لمشاريع .NET 6):

var builder = WebApplication.CreateBuilder(args);

// خدمات MVC
builder.Services.AddControllersWithViews();

// ذاكرة التخزين المؤقت للجلسة – مطلوبة للتحقق من صحة الرمز
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();

// تسجيل Doconut – أشِر إلى ملف الترخيص الخاص بك
builder.Services.AddDoconut(options =>
{
    options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
    options.MiddlewarePath = "/doconut";
    options.ResourcesPath = "/doconut-res";
    options.UnsafeMode = false; // احتفظ بالأمان الافتراضي
});

var app = builder.Build();

// يجب تشغيل الجلسة قبل Middleware المشاهد
app.UseSession();

// يجب ربط Middleware Doconut بالمسار المُكوَّن أعلاه.
// انظر وثائق Doconut للحصول على استدعاء التعيين الدقيق (مثال: app.Map("/doconut", …)).

app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapDefaultControllerRoute());

app.Run();

نقاط رئيسية:

  • AddDistributedMemoryCache يوفر المخزن في الذاكرة الذي يحتاجه AddSession.
  • UseSession() يجب أن يظهر قبل وسطية Doconut؛ وإلا ستظهر لك رسالة الخطأ في وقت التشغيل “Session middleware not configured.”
  • MiddlewarePath وResourcesPath هما سلاسل تنسيق – يجب أن يتطابق فرع الوسطية الفعلي مع المسار الذي تُكوّنه.

3. إنشاء عرض مدير الملفات

إنشاء Views/File/Index.cshtml. يدرج الملفات ويوفر إجراءات للتنزيل والحذف وعرض PDF.

@model List<string>
<h2>Document Library</h2>
<table>
    <thead><tr><th>Name</th><th>Actions</th></tr></thead>
    <tbody>
@foreach (var f in Model)
{
    <tr>
        <td>@f</td>
        <td>
            <a asp-action="Download" asp-route-name="@f">Download</a> |
            <a asp-action="Delete"   asp-route-name="@f">Delete</a> |
            @if (Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
            {
                <a asp-action="ViewPdf" asp-route-name="@f">View PDF</a>
            }
        </td>
    </tr>
}
    </tbody>
</table>

عند نقر المستخدم على عرض PDF، الإجراء ViewPdf ينشئ رمزًا ويعيد عرضًا ثانيًا يستضيف عنصر واجهة المشاهد.


4. عرض عارض Doconut

إنشاء Views/File/ViewPdf.cshtml. تحتاج الصفحة فقط إلى عنصر حاوية؛ يتم تحميل عنصر واجهة JavaScript من الموارد المضمنة.

@{
    var token = ViewBag.Token as string;
    var basePath = ViewBag.BasePath as string;
    var resPath = ViewBag.ResPath as string;
}
<h2>PDF Preview</h2>
<div id="div_ctlDoc"></div>

<script src="@($"{basePath}/docViewer.js")"></script>
<link rel="stylesheet" href="@($"{basePath}/docViewer.css")" />

<script>
    $('#div_ctlDoc').docViewer({
        AccessToken: '@token',
        BasePath: '@basePath',
        ResPath: '@resPath',
        FitType: 'width',
        showThumbs: true,
        autoLoad: true,
        onError: function (msg) { console.error(msg); }
    });
</script>

يقرأ عنصر الواجهة AccessToken الذي قدمته، ويتواصل مع نقطة النهاية /doconut/DocImage.axd، ويُبث كل صفحة كصورة. نظرًا لأن الرمز مرتبط بجلسة ASP.NET الحالية، لا يمكن للمستخدم نسخ الرابط وعرض المستند من متصفح آخر دون ملف تعريف الارتباط للجلسة نفسه.


5. معالجة انتهاء صلاحية الرمز والأمان

الوقت الافتراضي لانتهاء صلاحية الرمز في Doconut هو 60 دقيقة (قابل للتكوين عبر DocOptions.TimeOut). إذا تلقى العارض “Document session not found” أو “You Are Not Authorized To View This Page”، فإن الجلسة إما انتهت أو الطلب قادم من سياق متصفح مختلف.

العلاجات الشائعة:

  • تحديث الصفحة – سيولد المتحكم رمزًا جديدًا.
  • زيادة مهلة الانتهاء – مرّر DocOptions مخصصًا عند فتح المستند:
var options = new DocOptions { TimeOut = TimeSpan.FromHours(2) };
var token = await _viewer.OpenDocumentAsync(
    path,
    new Doconut.PdfConfig { AllowSearch = true },
    options,
    CancellationToken.None);
  • إعدادات عبر الأصل – تأكد من أن السمة SameSite على ملف تعريف الارتباط للجلسة متوافقة مع نطاق الواجهة الأمامية الخاص بك. السمة الافتراضية Lax تعمل لمعظم البوابات ذات الأصل نفسه.

6. توسيع المدير (اختياري)

مدير الملفات الأساسي يعمل بالفعل، لكن قد ترغب في إضافة:

  • رفع – نموذج بسيط يرسل IFormFile ويحفظه في _root.
  • تنقل المجلدات – عدّل الإجراء Index لقبول مسار نسبي وحمايته من عبور الدليل (Path.GetFullPath + StartsWith(_root) فحص).
  • بحث – صَفِّ files حسب الاسم قبل تمريره إلى العرض.

جميع هذه الإضافات تبقى ضمن نمط MVC نفسه وتستمر في الاستفادة من عارض Doconut المحمي بجلسة.


7. ما حققته

  • مدير ملفات ASP.NET MVC مجاني – لا مكتبات واجهة مستخدم من طرف ثالث، ولا رسوم ترخيص.
  • عرض PDF داخل المتصفح عبر عارض Doconut الشامل، مما يجنب الحاجة إلى تثبيت Office أو Adobe على العميل.
  • وصول آمن قائم على الرموز يستخدم حالة جلسة ASP.NET، مما يمنع مشاركة الروابط عشوائيًا.
  • قاعدة شفرة واحدة تعمل مع .NET 6 و .NET 8 ويمكن نقلها إلى Razor Pages أو APIs الحد الأدنى مع تغيير فقط استدعاءات التسجيل (AddDoconut, UseSession).

نشر التطبيق على IIS أو Azure App Service أو Docker – تكوين Program.cs نفسه يعمل في كل مكان لأن Doconut يعمل على .NET 6+ ولا يتطلب أي مكونات Office أصلية.

#ASP.NET MVC#File Manager#PDF Viewer#.NET#Doconut#مدير الملفات#عارض PDF