From 1cc617de4264744e9edd54d43017c480521a4f84 Mon Sep 17 00:00:00 2001 From: OlgunR Date: Mon, 8 Jun 2026 16:59:57 +0200 Subject: [PATCH] Enhance PDF viewing experience with new document viewer - Replaced button in `Details.cshtml` with a link to a new document viewer page. - Created `DocumentViewer.cshtml` to display PDFs using an iframe, with a back button and a link to an experimental DevExpress viewer. - Introduced `DocumentViewerModel` in `DocumentViewer.cshtml.cs` for handling invoice ID and PDF URL. - Updated `OnGetAsync` in `ViewPdf.cshtml.cs` to set `Content-Disposition` to inline for better PDF rendering in the browser. --- .../Pages/Invoices/Details.cshtml | 6 ++-- .../Pages/Invoices/DocumentViewer.cshtml | 33 +++++++++++++++++++ .../Pages/Invoices/DocumentViewer.cshtml.cs | 17 ++++++++++ .../Pages/Invoices/ViewPdf.cshtml.cs | 7 ++-- 4 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml create mode 100644 DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml.cs diff --git a/DXApp.TemplateKitProject/Pages/Invoices/Details.cshtml b/DXApp.TemplateKitProject/Pages/Invoices/Details.cshtml index d0f8b2b..85bda12 100644 --- a/DXApp.TemplateKitProject/Pages/Invoices/Details.cshtml +++ b/DXApp.TemplateKitProject/Pages/Invoices/Details.cshtml @@ -16,10 +16,10 @@ @if (!string.IsNullOrEmpty(Model.Invoice?.ResultFilePath)) { - + } @if (Model.Invoice is null) diff --git a/DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml b/DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml new file mode 100644 index 0000000..2add8b7 --- /dev/null +++ b/DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml @@ -0,0 +1,33 @@ +@page +@model DXApp.TemplateKitProject.Pages.Invoices.DocumentViewerModel +@{ + ViewData["Title"] = "Dokument Viewer"; + var pdfUrl = Model.PdfUrl; +} + +
+
+
Rechnung @Model.Id - Dokument
+
+ Zurück zur Übersicht + + + DevExpress Viewer (experimental) + +
+
+ +
+ @* Solide, funktionierende Baseline: Browser-internen PDF-Renderer verwenden *@ + +
+ + @* Hinweis: + - Diese Seite zeigt aktuell das PDF per einfachem iframe (funktioniert zuverlässig). + - Nächster Commit: wir ersetzen iframe durch DevExpress WebDocumentViewer oder laden diesen zusätzlich. + - Der Link "DevExpress Viewer (experimental)" ist ein Platzhalter; wir implementieren die Route /Invoices/DocumentViewerDevExpress in einem der nächsten Schritte. + *@ +
\ No newline at end of file diff --git a/DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml.cs b/DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml.cs new file mode 100644 index 0000000..021c7fc --- /dev/null +++ b/DXApp.TemplateKitProject/Pages/Invoices/DocumentViewer.cshtml.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace DXApp.TemplateKitProject.Pages.Invoices; + +public class DocumentViewerModel : PageModel +{ + [BindProperty(SupportsGet = true)] + public int Id { get; set; } + + public string PdfUrl => $"/Invoices/ViewPdf?id={Id}"; + + public void OnGet() + { + // Keine serverseitige Logik nötig für die erste Version. + } +} \ No newline at end of file diff --git a/DXApp.TemplateKitProject/Pages/Invoices/ViewPdf.cshtml.cs b/DXApp.TemplateKitProject/Pages/Invoices/ViewPdf.cshtml.cs index a13f182..83d5017 100644 --- a/DXApp.TemplateKitProject/Pages/Invoices/ViewPdf.cshtml.cs +++ b/DXApp.TemplateKitProject/Pages/Invoices/ViewPdf.cshtml.cs @@ -18,7 +18,6 @@ public class ViewPdfModel : PageModel public async Task OnGetAsync(int id) { - // Sicherheit: defensive checks, gleiche Logik wie CustomReportStorageWebExtension var invoice = await _db.ZugferdInvoices .AsNoTracking() .FirstOrDefaultAsync(i => i.Id == id); @@ -35,6 +34,10 @@ public class ViewPdfModel : PageModel var bytes = await System.IO.File.ReadAllBytesAsync(invoice.ResultFilePath); _logger.LogInformation("ViewPdf: Invoice {Id} ausgeliefert ({Size} Bytes).", id, bytes.Length); - return File(bytes, "application/pdf", $"{Path.GetFileName(invoice.ResultFilePath)}"); + // Wichtig: keine "attachment" Content-Disposition setzen + // wir setzen inline (oder lassen es weg) damit Browser im Viewer darstellt + Response.Headers["Content-Disposition"] = $"inline; filename=\"{Path.GetFileName(invoice.ResultFilePath)}\""; + + return File(bytes, "application/pdf"); } } \ No newline at end of file