ฟรี ASP.NET MVC ตัวจัดการไฟล์พร้อมตัวดู PDF ในตัว
← Back to Blog••4 min read

ฟรี ASP.NET MVC ตัวจัดการไฟล์พร้อมตัวดู PDF ในตัว

สร้างตัวจัดการไฟล์ ASP.NET MVC ฟรีที่แสดง PDF

คุณต้องการหน้าที่แสดงรายการไฟล์ที่เก็บบนเซิร์ฟเวอร์ ให้ผู้ใช้ดาวน์โหลดหรือทำการลบไฟล์ และเปิดไฟล์ PDF ใด ๆ ในเบราว์เซอร์โดยไม่ออกจากเว็บไซต์ คู่มือด้านล่างจะแสดงวิธีทำเช่นนั้นโดยใช้ ASP.NET MVC ธรรมดา แคชเซสชันในตัว และตัวดูเอกสารสากลของ Doconut


1. สร้างแอปพลิเคชัน MVC ขั้นพื้นฐาน

สร้างโปรเจกต์ MVC ใหม่ใน Visual Studio (ทุกเวอร์ชัน รวมถึง Community Edition ที่ฟรี)

Add a FileController that will host the file‑manager actions:

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();

        // The viewer token is created here (see section 2)
        var token = await _viewer.OpenDocumentAsync(
            path,
            new Doconut.PdfConfig { AllowSearch = true },
            new DocOptions(),
            CancellationToken.None);

        ViewBag.Token = token;
        ViewBag.BasePath = "doconut";          // matches the middleware branch
        ViewBag.ResPath = "doconut-res/images";// embedded resources
        return View();
    }

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

คอนโทรลเลอร์ทำสามอย่าง:

  1. Index – อ่านโฟลเดอร์ App_Data/Docs และส่งชื่อไฟล์ไปยังวิว
  2. Download / Delete – การกระทำ MVC มาตรฐานที่ใช้ตัวช่วย PhysicalFile ในตัว
  3. ViewPdf – เปิด PDF ที่เลือกด้วย Doconut รับโทเคนความปลอดภัยและส่งต่อไปยัง Razor view

2. ตั้งค่า Session State และบริการของ Doconut

ตัวดูของ Doconut พึ่งพา ASP.NET session state เพื่อปกป้องโทเคนที่ระบุเอกสาร เพิ่มบริการที่จำเป็นใน Program.cs (หรือ Startup.cs สำหรับโครงการ .NET 6):

var builder = WebApplication.CreateBuilder(args);

// MVC services
builder.Services.AddControllersWithViews();

// Session cache – required for token validation
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();

// Doconut registration – point to your license file
builder.Services.AddDoconut(options =>
{
    options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
    options.MiddlewarePath = "/doconut";
    options.ResourcesPath = "/doconut-res";
    options.UnsafeMode = false; // keep the default security
});

var app = builder.Build();

// Session must run before the viewer middleware
app.UseSession();

// The Doconut middleware must be mapped to the path configured above.
// See Doconut documentation for the exact mapping call (e.g., app.Map("/doconut", …)).

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

app.Run();

จุดสำคัญ:

  • AddDistributedMemoryCache จัดหาที่เก็บข้อมูลในหน่วยความจำที่ AddSession ต้องการ
  • UseSession() ต้อง ปรากฏก่อน middleware ของ Doconut; หากไม่เช่นนั้นคุณจะเจอข้อผิดพลาด runtime “Session middleware not configured.”
  • MiddlewarePath และ ResourcesPath เป็นสตริงประสานงาน – สาขา middleware จริงต้องตรงกับพาธที่คุณกำหนด

middleware ของ Doconut ต้องถูกแมปไปยังพาธที่กำหนดไว้ข้างต้น

ดูเอกสารของ Doconut เพื่อดูวิธีแมปที่แน่นอน (เช่น app.Map("/doconut", …))

3. สร้างมุมมอง File‑Manager

สร้าง 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>

เมื่อผู้ใช้คลิก View PDF การทำงาน ViewPdf จะสร้างโทเค็นและส่งคืนมุมมองที่สองซึ่งโฮสต์วิดเจ็ตตัวดูเอกสาร


4. แสดงผล Doconut Viewer

สร้าง 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 ที่คุณส่งให้, ติดต่อ endpoint /doconut/DocImage.axd, และสตรีมแต่ละหน้าเป็นภาพ. เนื่องจากโทเค็นผูกกับเซสชัน ASP.NET ปัจจุบัน, ผู้ใช้ไม่สามารถคัดลอก URL แล้วดูเอกสารจากเบราว์เซอร์อื่นได้หากไม่มีคุกกี้เซสชันเดียวกัน


5. การจัดการการหมดอายุของโทเค็นและความปลอดภัย

ค่า timeout เริ่มต้นของโทเค็นใน Doconut คือ 60 นาที (สามารถกำหนดค่าได้ผ่าน DocOptions.TimeOut). หากตัวดูเอกสารได้รับข้อความ “Document session not found” หรือ “You Are Not Authorized To View This Page” หมายความว่าเซสชันได้หมดอายุหรือคำขอมาจากบริบทของเบราว์เซอร์ที่แตกต่างกัน

วิธีแก้ไขทั่วไป:

  • รีเฟรชหน้า – ตัวควบคุมจะสร้างโทเค็นใหม่
  • เพิ่มเวลา timeout – ส่ง DocOptions ที่กำหนดเองเมื่อเปิดเอกสาร:
var options = new DocOptions { TimeOut = TimeSpan.FromHours(2) };
var token = await _viewer.OpenDocumentAsync(
    path,
    new Doconut.PdfConfig { AllowSearch = true },
    options,
    CancellationToken.None);
  • การตั้งค่า Cross‑origin – ตรวจสอบให้แน่ใจว่าแอตทริบิวต์ SameSite ของคุกกี้เซสชันเข้ากันได้กับโดเมนส่วนหน้าของคุณ. ค่าเริ่มต้น Lax ทำงานได้กับพอร์ทัลที่มีต้นทางเดียวกันส่วนใหญ่

6. การขยายผู้จัดการ (Optional)

ตัวจัดการไฟล์หลักทำงานได้แล้ว, แต่คุณอาจต้องการเพิ่ม:

  • Upload – แบบฟอร์มง่ายที่โพสต์ IFormFile และบันทึกไปยัง _root
  • การนำทางโฟลเดอร์ – ปรับการทำงาน Index ให้รับเส้นทางสัมพันธ์และป้องกันการเดินทางไดเรกทอรี (Path.GetFullPath + การตรวจสอบ StartsWith(_root))
  • การค้นหา – กรอง files ตามชื่อก่อนส่งไปยังมุมมอง

ส่วนขยายทั้งหมดนี้ยังคงอยู่ในรูปแบบ MVC เดียวกันและยังคงได้รับประโยชน์จาก Doconut viewer ที่ป้องกันด้วยเซสชันเดียวกัน


7. สิ่งที่คุณได้ทำสำเร็จ

  • ฟรี ASP.NET MVC file manager – ไม่ใช้ไลบรารี UI ของบุคคลที่สาม, ไม่มีค่าลิขสิทธิ์
  • การแสดงผล PDF ในเบราว์เซอร์ ผ่าน Doconut viewer สากล, หลีกเลี่ยงความจำเป็นในการติดตั้ง Office หรือ Adobe บนเครื่องลูกข่าย
  • การเข้าถึงแบบโทเค็นที่ปลอดภัย ที่ใช้สถานะเซสชันของ ASP.NET, ป้องกันการแชร์ URL อย่างอิสระ
  • ฐานโค้ดเดียว ที่ทำงานได้กับ .NET 6 และ .NET 8 และสามารถพอร์ตไปยัง Razor Pages หรือ Minimal APIs ได้โดยเปลี่ยนเพียงการเรียกลงทะเบียน (AddDoconut, UseSession)

ปรับใช้แอปไปยัง IIS, Azure App Service, หรือ Docker – การกำหนดค่า Program.cs เดียวกันทำงานได้ทุกที่เนื่องจาก Doconut ทำงานบน .NET 6+ และไม่ต้องการคอมโพเนนต์ Office แบบเนทีฟใด ๆ

#ASP.NET MVC#File Manager#PDF Viewer#.NET#Doconut#ตัวจัดการไฟล์#ตัวดู PDF