Betrachter ist zustandslos — Wie man einen minimalen .NET 8 Open-Endpunkt erstellt
← Back to Blog••4 min read

Betrachter ist zustandslos — Wie man einen minimalen .NET 8 Open-Endpunkt erstellt

Betrachter ist zustandslos — per Design

Viewer behält keine anfragebezogenen Dokumentdaten. Es ist eine versiegelte Klasse, sie implementiert niemals IDisposable, und jedes Dokument, das Sie öffnen, lebt in einer separaten Sitzung, die vom Cache des Frameworks verwaltet wird. Deshalb können Sie eine einzelne Viewer‑Instanz überall in Ihrer ASP.NET Core‑App injizieren und sicher von vielen gleichzeitigen Anfragen aus aufrufen.


Folgen eines zustandslosen Dienstes

  • Keine versteckten Ressourcen – der Dienst selbst allokiert nie große Puffer, die einer expliziten Bereinigung bedürfen.
  • Thread‑sicher per Default – weil kein anfrage‑spezifischer Zustand gespeichert wird, kann dieselbe Viewer‑Instanz von mehreren Threads ohne Sperren verwendet werden.
  • Skalierbare Bereitstellungen – horizontales Skalieren funktioniert sofort; Sie benötigen keine Sticky Sessions oder Server‑Affinität, nur das Session‑Token, das der Client hält.

Alle dokument‑spezifischen Informationen (Seiten, Anmerkungen, Suchindex) werden in einer Sitzung gespeichert, die von OpenDocumentAsync erstellt wird. Die Sitzung wird in IMemoryCache (oder jedem von Ihnen konfigurierten IDistributedCache) abgelegt und läuft nach einer Inaktivitätsperiode (Standard 60 Minuten) automatisch ab. Wenn Sie fertig sind, können Sie CloseDocument aufrufen, um den Cache‑Eintrag vorzeitig zu entfernen.


Registrieren des zustandslosen Viewers

Da Viewer keinen veränderlichen Zustand hat, registrieren Sie es einmalig beim Start:

builder.Services.AddDoconut();               // registriert Viewer und erforderliche Middleware
builder.Services.AddSession();               // erforderlich für Token-Sicherheit
builder.Services.AddDistributedMemoryCache(); // einfacher Cache für die Demo

Der Aufruf von AddDoconut verbindet außerdem die Middleware, die die statischen Ressourcen des Viewers bereitstellt. Nachdem die Services eingerichtet sind, können Sie Viewer in jeder Endpunkt‑Signatur anfordern.


Minimaler Open‑Document‑Endpunkt (Net‑8 Beispiel)

Der folgende Code ist das exakte Snippet aus der offiziellen Dokumentation und funktioniert sofort in einem .NET 8 Minimal‑API‑Projekt:

app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
    var token = await viewer.OpenDocumentAsync($"files/{fileName}");
    return Results.Content(token, "text/plain");
});

Was der Code macht

  1. Akzeptiert einen Dateinamen – der Client teilt dem Server mit, welche Datei unter wwwroot/files zu öffnen ist.
  2. Ruft OpenDocumentAsync auf – der zustandslose Viewer erstellt eine neue Sitzung, speichert sie im Cache und gibt ein undurchsichtiges Token zurück.
  3. Gibt das Token als Klartext zurück – der Client erhält nur das Token; der Server sendet in dieser Antwort niemals die Dokumentbytes.

Da Viewer keine Dokumentdaten hält, benötigt der Endpunkt keine using‑Blöcke, keine Dispose‑Aufrufe und keine per‑Request‑Fabriken. Das Token ist das einzige Anmeldezeichen, das der Client jemals an das Viewer‑Widget zurücksendet (objViewer.View(token) im Front‑End).


Verwendung des Tokens auf der Client‑Seite

Nachdem das Token zurückgegeben wurde, ruft das Front‑End‑Widget objViewer.View(token) auf. Das Widget fügt dann bei jeder nachfolgenden Anfrage für Seitenbilder, Suche oder Anmerkungsaktionen dasselbe Token hinzu. Der Server prüft das Token gegen die Sitzung, die das Dokument ursprünglich geöffnet hat. Wird das Token aus einer anderen Browser‑Sitzung präsentiert, gibt der Viewer einen Autorisierungsfehler zurück, was das beabsichtigte Sicherheitsverhalten ist.


Vorzeitiges Schließen einer Sitzung (optional)

Wenn Ihr Workflow weiß, dass ein Dokument nie wieder aufgerufen wird, können Sie den Cache‑Eintrag freigeben, indem Sie CloseDocument auf dem Viewer aufrufen. Dadurch wird die Sitzung aus dem Cache entfernt und verhindert, dass der gleitende Ablauf‑Timer sie am Leben hält.


Zusammenfassung des zustandslosen Ablaufs

SchrittWas passiertWo der Zustand lebt
Viewer injizierenEine einzelne Viewer‑Instanz wird beim Start erstellt.Im DI‑Container (Singleton).
OpenDocumentAsyncLizenz geprüft → Sitzung erstellt → Token zurückgegeben.Sitzung gespeichert in IMemoryCache (oder verteiltem Cache).
Client rendertWidget sendet das Token bei jeder Anfrage.Das Token ist die einzige pro‑Dokument‑Daten, die der Client hält.
Sitzungsablauf / CloseDocumentCache‑Eintrag nach Zeitüberschreitung oder explizitem Schließen entfernt.Keine verbleibenden Ressourcen im Viewer‑Dienst.

Da der Dienst selbst niemals Dokumentdaten speichert, können Sie Ihre Webfarm sicher skalieren, Knoten austauschen oder die Anwendung neu starten, ohne dass ein benutzer‑sichtbarer Zustand verloren geht – nur das Token wird ungültig, wodurch der Client das Dokument erneut öffnen muss.


Bereitstellung des zustandslosen Viewers in Ihrer App

  1. Fügen Sie AddDoconut, AddSession und einen Cache‑Provider zu Program.cs hinzu.
  2. Fügen Sie das Open‑Endpoint‑Snippet in Ihre Minimal‑API‑Konfiguration ein.
  3. Übergeben Sie das zurückgegebene Token an objViewer.View(token) im Front‑End.

Sie haben nun eine vollständig zustandslose, produktionsbereite Dokument‑Open‑API, die Doconut’s Viewer‑Design nutzt.

#dotnet8#viewer#stateless#api#doconut#Betrachter#zustandslos