Darmowy menedżer plików ASP.NET MVC z wbudowaną przeglądarką PDF
← Back to Blog••5 min read

Darmowy menedżer plików ASP.NET MVC z wbudowaną przeglądarką PDF

Zbuduj darmowy menedżer plików ASP.NET MVC, który wyświetla PDF-y

Chcesz mieć stronę, która wyświetla listę plików przechowywanych na serwerze, umożliwia ich pobieranie lub usuwanie oraz otwiera każdy PDF w przeglądarce bez opuszczania witryny. Poniższy przewodnik pokazuje, jak zrobić to dokładnie przy użyciu czystego ASP.NET MVC, wbudowanej pamięci sesji i uniwersalnego przeglądarki dokumentów Doconut.


1. Utwórz minimalną aplikację MVC

Utwórz nowy projekt MVC w Visual Studio (dowolna edycja, w tym darmowa edycja Community).

Dodaj FileController, który będzie obsługiwał akcje menedżera plików:

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;
}

Kontroler wykonuje trzy czynności:

  1. Index – odczytuje folder App_Data/Docs i przekazuje nazwy plików do widoku.
  2. Download / Delete – standardowe akcje MVC, które używają wbudowanego pomocnika PhysicalFile.
  3. ViewPdf – otwiera wybrany PDF przy użyciu Doconut, otrzymuje token bezpieczeństwa i przekazuje go do widoku Razor.

2. Skonfiguruj stan sesji i usługi Doconut

Przeglądarka Doconut opiera się na stanie sesji ASP.NET, aby chronić token identyfikujący dokument. Dodaj wymagane usługi w Program.cs (lub Startup.cs dla projektów .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();

Kluczowe punkty:

  • AddDistributedMemoryCache zapewnia pamięć w‑ramce potrzebną AddSession.
  • UseSession() musi pojawić się przed middleware Doconut; w przeciwnym razie pojawi się błąd czasu wykonania „Session middleware not configured.”
  • MiddlewarePath i ResourcesPath są łańcuchami koordynacyjnymi – rzeczywisty branch middleware musi odpowiadać skonfigurowanej ścieżce.

3. Utwórz widok menedżera plików

Utwórz Views/File/Index.cshtml. Wyświetla listę plików i zapewnia akcje pobierania, usuwania oraz podglądu 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>

Gdy użytkownik kliknie View PDF, akcja ViewPdf tworzy token i zwraca drugi widok, który hostuje widget przeglądarki.


4. Renderuj przeglądarkę Doconut

Utwórz Views/File/ViewPdf.cshtml. Strona wymaga jedynie elementu kontenera; widget JavaScript jest ładowany z zasobów osadzonych.

@{
    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>

Widget odczytuje podany przez Ciebie AccessToken, kontaktuje się z endpointem /doconut/DocImage.axd i przesyła każdą stronę jako obraz. Ponieważ token jest powiązany z bieżącą sesją ASP.NET, użytkownik nie może skopiować adresu URL i wyświetlić dokumentu w innej przeglądarce bez tego samego ciasteczka sesji.


5. Obsługa wygaśnięcia tokenu i bezpieczeństwo

Domyślny limit czasu tokenu w Doconut wynosi 60 minut (można go skonfigurować poprzez DocOptions.TimeOut). Jeśli przeglądarka otrzyma „Document session not found” lub „You Are Not Authorized To View This Page”, sesja wygasła lub żądanie pochodzi z innego kontekstu przeglądarki.

Typowe rozwiązania:

  • Odśwież stronę – kontroler wygeneruje nowy token.
  • Zwiększ limit czasu – przekaż własny DocOptions przy otwieraniu dokumentu:
var options = new DocOptions { TimeOut = TimeSpan.FromHours(2) };
var token = await _viewer.OpenDocumentAsync(
    path,
    new Doconut.PdfConfig { AllowSearch = true },
    options,
    CancellationToken.None);
  • Ustawienia cross‑origin – upewnij się, że atrybut SameSite w ciasteczku sesji jest zgodny z domeną front‑endu. Domyślne Lax działa w większości portali o tej samej pochodzeniu.

6. Rozszerzanie menedżera (opcjonalnie)

Podstawowy menedżer plików jest już funkcjonalny, ale możesz chcieć dodać:

  • Upload – prosty formularz, który wysyła IFormFile i zapisuje go w _root.
  • Nawigacja po folderach – zmodyfikuj akcję Index, aby przyjmowała ścieżkę względną i chroniła ją przed traversą katalogów (Path.GetFullPath + sprawdzenie StartsWith(_root)).
  • Search – przefiltruj files po nazwie przed przekazaniem ich do widoku.

Wszystkie te rozszerzenia pozostają w ramach tego samego wzorca MVC i nadal korzystają z tego samego, chronionego sesją, widoku Doconut.


7. Co udało Ci się osiągnąć

  • Bezpłatny menedżer plików ASP.NET MVC – bez bibliotek UI innych firm, bez opłat licencyjnych.
  • Renderowanie PDF w przeglądarce za pomocą uniwersalnego widoku Doconut, eliminując potrzebę instalacji Office lub Adobe po stronie klienta.
  • Bezpieczny dostęp oparty na tokenie wykorzystujący stan sesji ASP.NET, zapobiegający dowolnemu udostępnianiu adresu URL.
  • Jedna baza kodu, działająca na .NET 6 i .NET 8 oraz możliwa do przeniesienia na Razor Pages lub minimalne API, przy zmianie jedynie wywołań rejestracji (AddDoconut, UseSession).

Wdroż aplikację na IIS, Azure App Service lub Docker – ta sama konfiguracja w Program.cs działa wszędzie, ponieważ Doconut działa na .NET 6+ i nie wymaga żadnych natywnych komponentów Office.

#ASP.NET MVC#File Manager#PDF Viewer#.NET#Doconut#Menedżer plików#Przeglądarka PDF