Kostenloser ASP.NET MVC Dateimanager mit integriertem PDF‑Betrachter
← Back to Blog••5 min read

Kostenloser ASP.NET MVC Dateimanager mit integriertem PDF‑Betrachter

Erstelle einen kostenlosen ASP.NET MVC Dateimanager, der PDFs anzeigt

Sie möchten eine Seite, die die auf dem Server gespeicherten Dateien auflistet, dem Benutzer das Herunterladen oder Löschen ermöglicht und jede PDF im Browser öffnet, ohne die Seite zu verlassen. Die folgende Anleitung zeigt Ihnen, wie Sie genau das mit einfachem ASP.NET MVC, dem integrierten Session‑Cache und Doconut’s universellem Dokumenten‑Viewer erreichen.


1. Erstelle eine minimale MVC‑Anwendung

Erstellen Sie ein neues MVC‑Projekt in Visual Studio (jede Edition, einschließlich der kostenlosen Community‑Edition).

Fügen Sie einen FileController hinzu, der die Dateimanager‑Aktionen bereitstellt:

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

Der Controller erledigt drei Dinge:

  1. Index – liest den Ordner App_Data/Docs und übergibt die Dateinamen an eine Ansicht.
  2. Download / Delete – Standard‑MVC‑Aktionen, die den integrierten PhysicalFile‑Helper verwenden.
  3. ViewPdf – öffnet das ausgewählte PDF mit Doconut, erhält ein Sicherheitstoken und übergibt es an eine Razor‑Ansicht.

2. Session‑State und Doconut‑Dienste einbinden

Der Viewer von Doconut nutzt den ASP.NET‑Session‑State, um das Token zu schützen, das ein Dokument identifiziert. Fügen Sie die erforderlichen Dienste in Program.cs (oder Startup.cs für .NET 6‑Projekte) hinzu:

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

Wichtige Punkte:

  • AddDistributedMemoryCache stellt den In‑Memory‑Speicher bereit, den AddSession benötigt.
  • UseSession() muss vor der Doconut‑Middleware aufgerufen werden; andernfalls erhalten Sie den Laufzeitfehler „Session middleware not configured.“
  • MiddlewarePath und ResourcesPath sind Koordinations‑Strings – der tatsächliche Middleware‑Zweig muss dem von Ihnen konfigurierten Pfad entsprechen.

3. Erstelle die Datei‑Manager‑Ansicht

Erstelle Views/File/Index.cshtml. Sie listet Dateien auf und bietet Aktionen zum Herunterladen, Löschen und Anzeigen von PDFs.

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

Wenn der Benutzer View PDF anklickt, erzeugt die ViewPdf‑Aktion ein Token und gibt eine zweite Ansicht zurück, die das Viewer‑Widget hostet.


4. Render den Doconut Viewer

Erstelle Views/File/ViewPdf.cshtml. Die Seite benötigt nur ein Container‑Element; das JavaScript‑Widget wird aus den eingebetteten Ressourcen geladen.

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

Das Widget liest das von Ihnen bereitgestellte AccessToken, kontaktiert den Endpunkt /doconut/DocImage.axd und streamt jede Seite als Bild. Da das Token an die aktuelle ASP.NET‑Sitzung gebunden ist, kann ein Benutzer die URL nicht kopieren und das Dokument in einem anderen Browser anzeigen, ohne das gleiche Sitzungs‑Cookie.


5. Umgang mit Token‑Ablauf und Sicherheit

Der Standard‑Token‑Timeout von Doconut beträgt 60 Minuten (über DocOptions.TimeOut konfigurierbar). Wenn das Viewer „Document session not found“ oder „You Are Not Authorized To View This Page“ zurückgibt, ist die Sitzung entweder abgelaufen oder die Anfrage stammt aus einem anderen Browser‑Kontext.

Typische Lösungen:

  • Seite neu laden – der Controller erzeugt ein neues Token.
  • Timeout erhöhen – übergeben Sie ein benutzerdefiniertes DocOptions beim Öffnen des Dokuments:
var options = new DocOptions { TimeOut = TimeSpan.FromHours(2) };
var token = await _viewer.OpenDocumentAsync(
    path,
    new Doconut.PdfConfig { AllowSearch = true },
    options,
    CancellationToken.None);
  • Cross‑Origin‑Setups – stellen Sie sicher, dass das SameSite‑Attribut des Sitzungs‑Cookies mit Ihrer Front‑End‑Domain kompatibel ist. Das Standard‑Lax funktioniert für die meisten Same‑Origin‑Portale.

6. Erweiterung des Managers (Optional)

Der Kern‑Dateimanager ist bereits funktionsfähig, Sie möchten jedoch möglicherweise hinzufügen:

  • Upload – ein einfaches Formular, das ein IFormFile postet und es in _root speichert.
  • Ordner‑Navigation – ändern Sie die Index‑Aktion, um einen relativen Pfad zu akzeptieren und ihn gegen Directory‑Traversal zu schützen (Path.GetFullPath + StartsWith(_root)‑Prüfung).
  • Suche – filtern Sie files nach Namen, bevor Sie sie an die Ansicht übergeben.

All diese Erweiterungen bleiben im selben MVC‑Muster und profitieren weiterhin vom gleichen sitzungs‑geschützten Doconut‑Viewer.


7. Was Sie erreicht haben

  • Ein kostenloser ASP.NET MVC‑Dateimanager – keine Drittanbieter‑UI‑Bibliotheken, keine Lizenzgebühren.
  • In‑Browser‑PDF‑Rendering über Doconut’s universellen Viewer, wodurch Office‑ oder Adobe‑Installationen auf dem Client entfallen.
  • Sichere token‑basierte Zugriffskontrolle, die den ASP.NET‑Sitzungszustand nutzt und das beliebige Teilen von URLs verhindert.
  • Eine einzige Codebasis, die für .NET 6 und .NET 8 funktioniert und mit nur den Registrierungsaufrufen (AddDoconut, UseSession) zu Razor Pages oder Minimal‑APIs portiert werden kann.

Deployen Sie die Anwendung zu IIS, Azure App Service oder Docker – die gleiche Program.cs‑Konfiguration funktioniert überall, da Doconut auf .NET 6+ läuft und keine nativen Office‑Komponenten benötigt.

#ASP.NET MVC#File Manager#PDF Viewer#.NET#Doconut#Dateimanager#PDF‑Betrachter