Wie man Razor in PDF bei Blazor Server mit C# konvertiert
Die Migration von Kaizen.io HTML-zu-PDFzu IronPDF ersetzt einen selbstgehosteten Docker-Container, der über HTTP exponiert wird, durch eine In-Prozess .NET-Bibliothek. Kaizen.io HTML-zu-PDFwird nur als Docker-Image kaizenio.azurecr.io/html-to-pdf bereitgestellt und bietet einen einzigen REST-Endpunkt bei POST /html-to-pdf auf Port 8080 — es gibt kein offizielles .NET SDK oder NuGet-Paket, daher muss jeder C#-Aufruf HttpClient gegen den laufenden Container manuell erstellt werden. In dieser Anleitung wird beschrieben, wie Sie dieses Muster gegen IronPDFs ChromePdfRenderer austauschen können.
Warum von Kaizen.io zu IronPDF migrieren
Die Container-API Herausforderungen
Kaizen.io HTML-to-PDF ist ein Docker-Container mit einer bewusst kleinen v1.x API, und die C#-Integrationsgeschichte ist das, was Sie selbst auf HttpClient aufbauen. Diese Gestaltung hat in der Produktion echte Grenzen:
-
Container zum Betreiben: Sie betreiben, überwachen und aktualisieren
kaizenio.azurecr.io/html-to-pdf:latestan einem Ort, der von Ihrer App erreichbar ist — lokaler Docker, Sidecar oder ein separater Host. -
Kein .NET SDK: Jeder C#-Aufruf wird manuell als
HttpClientPOST + JSON erstellt. Kein IntelliSense, keine Compile-Zeit-Checks zur Antragsgestaltung. -
Winzige v1.x API-Oberfläche: Der dokumentierte JSON-Body akzeptiert nur ein
htmlFeld. URL-zu-PDF, benutzerdefinierte Stylesheets, Kopf-/Fußzeilen, Seitengröße, Ausrichtung und Ränder werden als Roadmap-Elemente aufgeführt, nicht als versandfertige Funktionen — alles über das Rendern einer HTML-Zeichenkette hinaus muss im HTML selbst ausgedrückt werden, typischerweise über@pageCSS und absolut positionierte Div-Elemente. -
Keine Seitennummernunterstützung: Die API hat keine
{page}/{total}Platzhalter, sodass Fußzeilen wie "Seite X von Y" serverseitig nicht erstellt werden können. -
HTTP Round-Trip pro PDF: Selbst wenn der Container auf
localhostläuft, erfolgt bei jedem PDF eine JSON-Serialisierung und ein Socket-Hop. - Wasserzeichen in der kostenlosen Version: Ohne das in der Containerumgebung gesetzte
KAIZEN_PDF_LICENSE-Umgebungsvariable wird das Ergebnis mit einem Wasserzeichen versehen.
Kaizen.io vs IronPDF Vergleich
| Feature | Kaizen.io HTML-zu-PDF | IronPDF |
|---|---|---|
| Verteilung | Docker-Image kaizenio.azurecr.io/html-to-pdf |
NuGet IronPdf |
| C#-Integration | Manuell erstelltes HttpClient POST (kein SDK) |
Streng typisierte ChromePdfRenderer API |
| Prozessmodell | Prozessfremder Container | In Bearbeitung |
| Endpunkt-Oberfläche (v1.x) | POST /html-to-pdf mit { "html": ... } |
Methoden für HTML, Datei, URL |
| URL-Eingabe | Fahrplan | RenderUrlAsPdf(url) |
| Header / Footer | Nicht in der v1.x-API; gefälscht via feststehendes CSS | TextHeader/Footer und HtmlHeader/Footer |
| Seitenzahlen | Nicht unterstützt | {page}und {total-pages}Platzhalter |
| Seitengröße / Ausrichtung | Eingebettetes @page CSS in HTML |
RenderingOptions.PaperSize usw. |
| Lizenzierung | Einmalige Lizenz; mit Wasserzeichen versehene Gratisstufe | Kommerziell (jährlich oder unbefristet) |
Für Teams, die auf modernes .NET standardisieren, entfernt IronPDF den Sidecar-Container und den HTTP-Hoop vom Anfragpfad und bietet eine stark typisierte Konfigurationsoberfläche.
Migrationskomplexitätsbewertung
Geschätzter Aufwand nach Merkmalen
| Feature | Komplexität der Migration |
|---|---|
| Grundlegendes HTML zu PDF | Sehr niedrig |
| HTML-Datei in PDF | Sehr niedrig |
| URL zu PDF | Niedrig (Kaizen v1.x hat keinen URL-Endpunkt — Umgehung wird vollständig ersetzt) |
| Kopf-/Fußzeilen | Mittel (gefälschte CSS-Divs werden durch echte Header-Zonen ersetzt) |
| Seitenzahlen | Neue Fähigkeit (nicht verfügbar in Kaizen v1.x) |
| Seite Einstellungen | Niedrig (@page CSS verschiebt sich zu RenderingOptions) |
Paradigmen-Verschiebung
Die grundlegende Verschiebung geht von prozessfremden HTTP-Aufrufen zu einem Docker-Container zu In-Prozess-Rendering:
Kaizen.io: HttpClient.PostAsync("http://.../html-to-pdf", { html }) → byte[]
IronPDF: ChromePdfRenderer → RenderHtmlAsPdf(html) → PdfDocument
Bevor Sie beginnen
Voraussetzungen
- .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5+
- NuGet -Zugriff: Möglichkeit zur Installation von NuGet -Paketen
- IronPDF -Lizenz: Ihren Lizenzschlüssel erhalten Sie unter IronPDF.
Paketänderungen
Es gibt kein Kaizen NuGet-Paket, das entfernt werden müsste — Kaizen wird nur als Docker-Image geliefert. Stoppen Sie den Container und fügen Sie das IronPDF-Paket hinzu:
# Stop and remove the running Kaizen container (if any)
docker stop kaizen-pdf
docker rm kaizen-pdf
# Install IronPDF
dotnet add package IronPdf
# Stop and remove the running Kaizen container (if any)
docker stop kaizen-pdf
docker rm kaizen-pdf
# Install IronPDF
dotnet add package IronPdf
Lizenz-Konfiguration
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Kaizen.io-Verwendung identifizieren
Da Kaizen kein SDK hat, sehen Aufrufe wie generische HttpClient POSTs aus. Suchen Sie nach dem Endpunkt, dem Bildnamen und der Lizenz-Umgebungsvariable anstelle eines Namespace:
grep -r "html-to-pdf\|KAIZEN_PDF_LICENSE\|kaizenio.azurecr.io\|localhost:8080" \
--include="*.cs" --include="*.json" --include="*.yml" .
grep -r "html-to-pdf\|KAIZEN_PDF_LICENSE\|kaizenio.azurecr.io\|localhost:8080" \
--include="*.cs" --include="*.json" --include="*.yml" .
Komplette API-Referenz
Konzeptabbildungen
Es gibt keine Kaizen .NET-Klasse zum Abbilden — nur die JSON-Antragsform und die Konventionen, die Sie darum gebaut haben.
| Kaizen.io Konzept | IronPDF-Äquivalent |
|---|---|
HttpClient + POST /html-to-pdf |
ChromePdfRenderer |
JSON { "html": "..." }Body |
RenderHtmlAsPdf(string html) |
| (No URL field in v1.x) | RenderUrlAsPdf(string url) |
| (No file field in v1.x) | RenderHtmlFileAsPdf(string path) |
Inline @page CSS für Größe |
RenderingOptions.PaperSize |
Inline @page CSS für Ausrichtung |
RenderingOptions.PaperOrientation |
Inline @page { margin: ... } |
RenderingOptions.MarginTop/Bottom/Left/Right |
Fest verankerter <div class='header'> Hack |
RenderingOptions.TextHeader / HtmlHeader |
Fest verankerter <div class='footer'> Hack |
RenderingOptions.TextFooter / HtmlFooter |
HttpClient.PostAsync |
RenderHtmlAsPdfAsync |
Container-Umgebungsvariable KAIZEN_PDF_LICENSE |
IronPdf.License.LicenseKey |
HTTP byte[] Antwort |
pdf.BinaryData / pdf.SaveAs(path) |
Platzhalter-Zuordnungen
Kaizen v1.x hat keine serverseitigen Platzhalter. Wenn Sie zuvor Zeichenketten in das HTML-Subsystem eingefügt haben, bevor Sie es abgeschickt haben, wechseln Sie zu den Renderzeit-Platzhaltern von IronPDF:
| Was Sie früher gemacht haben | IronPDF Platzhalter |
|---|---|
html.Replace("{page}", currentPage.ToString()) |
{page} |
html.Replace("{total}", total.ToString()) |
{total-pages} |
html.Replace("{date}", DateTime.Now.ToShortDateString()) |
{date} |
html.Replace("{title}", docTitle) |
{html-title} |
Beispiele für die Code-Migration
Beispiel 1: Grundlegendes HTML zu PDF
Before (Kaizen.io — POST JSON to the container):
// Container must be running:
// docker run -d -p 8080:8080 -e KAIZEN_PDF_LICENSE=... \
// kaizenio.azurecr.io/html-to-pdf:latest
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
var payload = JsonSerializer.Serialize(new { html = "<html><body><h1>Hello World</h1></body></html>" });
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await http.PostAsync("http://localhost:8080/html-to-pdf", content);
response.EnsureSuccessStatusCode();
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes("output.pdf", pdfBytes);
}
}
// Container must be running:
// docker run -d -p 8080:8080 -e KAIZEN_PDF_LICENSE=... \
// kaizenio.azurecr.io/html-to-pdf:latest
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
var payload = JsonSerializer.Serialize(new { html = "<html><body><h1>Hello World</h1></body></html>" });
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await http.PostAsync("http://localhost:8080/html-to-pdf", content);
response.EnsureSuccessStatusCode();
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes("output.pdf", pdfBytes);
}
}
Imports System.IO
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
Dim payload = JsonSerializer.Serialize(New With {.html = "<html><body><h1>Hello World</h1></body></html>"})
Dim content As New StringContent(payload, Encoding.UTF8, "application/json")
Dim response = Await http.PostAsync("http://localhost:8080/html-to-pdf", content)
response.EnsureSuccessStatusCode()
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()
File.WriteAllBytes("output.pdf", pdfBytes)
End Using
End Function
End Module
Nach (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var html = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var html = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports System.IO
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html = "<html><body><h1>Hello World</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Sub
End Class
Der Kaizen.io-Ansatz serialisiert JSON, postet es an den REST-Endpunkt des Containers, überprüft den Statuscode, liest die Antwort als Bytes und schreibt diese Bytes auf die Festplatte. IronPDF's ChromePdfRenderer läuft im Prozess — RenderHtmlAsPdf() gibt einen PdfDocument mit einer SaveAs() Methode zurück, sodass der Round-Trip und das manuelle Byte-Handling entfallen. Weitere Rendering-Optionen finden Sie in der HTML to PDF Dokumentation.
Beispiel 2: HTML-Datei in PDF mit Seiteneinstellungen
Kaizen v1.x hat keinen Dateiendpunkt und keine Seitengestaltungsfelder — Sie lesen die Datei selbst und betten Seitengröße/Ausrichtung in @page CSS ein.
Vor (Kaizen.io):
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var body = File.ReadAllText("input.html");
var html = "<style>@page { size: A4 portrait; }</style>" + body;
using var http = new HttpClient();
var payload = JsonSerializer.Serialize(new { html });
var response = await http.PostAsync(
"http://localhost:8080/html-to-pdf",
new StringContent(payload, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
File.WriteAllBytes("document.pdf", await response.Content.ReadAsByteArrayAsync());
}
}
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var body = File.ReadAllText("input.html");
var html = "<style>@page { size: A4 portrait; }</style>" + body;
using var http = new HttpClient();
var payload = JsonSerializer.Serialize(new { html });
var response = await http.PostAsync(
"http://localhost:8080/html-to-pdf",
new StringContent(payload, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
File.WriteAllBytes("document.pdf", await response.Content.ReadAsByteArrayAsync());
}
}
Imports System.IO
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Dim body = File.ReadAllText("input.html")
Dim html = "<style>@page { size: A4 portrait; }</style>" & body
Using http As New HttpClient()
Dim payload = JsonSerializer.Serialize(New With {Key .html = html})
Dim response = Await http.PostAsync(
"http://localhost:8080/html-to-pdf",
New StringContent(payload, Encoding.UTF8, "application/json"))
response.EnsureSuccessStatusCode()
File.WriteAllBytes("document.pdf", Await response.Content.ReadAsByteArrayAsync())
End Using
End Function
End Module
Nach (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait;
var pdf = renderer.RenderHtmlFileAsPdf("input.html");
pdf.SaveAs("document.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait;
var pdf = renderer.RenderHtmlFileAsPdf("input.html");
pdf.SaveAs("document.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait
Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
pdf.SaveAs("document.pdf")
End Sub
End Class
RenderHtmlFileAsPdf() liest die Datei direkt, und Seitengröße und Ausrichtung verschieben sich von Inline-@page CSS zu RenderingOptions Eigenschaften.
Beispiel 3: URL in PDF mit Kopf- und Fußzeilen
Kaizen v1.x hat keinen ConvertUrl, keine Kopf-/Fußzeilenfelder und keine Seitennummernplatzhalter. Der Workaround besteht darin, die Seite selbst abzurufen und mit @page CSS und fest verankerten Divs zu umgeben, um Kopf-/Fußzeile zu simulieren — ohne Möglichkeit, Seitennummern zu rendern.
Vor (Kaizen.io):
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
var page = await http.GetStringAsync("https://example.com");
var html = $@"<!doctype html><html><head><style>
@page {{margin: 20mm;}}
.h {{position: fixed; top: -15mm; left: 0; right: 0; text-align: center;}}
.f {{position: fixed; bottom: -15mm; left: 0; right: 0; text-align: center;}}
</style></head><body>
<div class='h'>Company Header</div>
<div class='f'>Footer (page numbers unsupported in Kaizen v1.x)</div>
{page}
</body></html>";
var payload = JsonSerializer.Serialize(new { html });
var response = await http.PostAsync(
"http://localhost:8080/html-to-pdf",
new StringContent(payload, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
File.WriteAllBytes("webpage.pdf", await response.Content.ReadAsByteArrayAsync());
}
}
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
var page = await http.GetStringAsync("https://example.com");
var html = $@"<!doctype html><html><head><style>
@page {{margin: 20mm;}}
.h {{position: fixed; top: -15mm; left: 0; right: 0; text-align: center;}}
.f {{position: fixed; bottom: -15mm; left: 0; right: 0; text-align: center;}}
</style></head><body>
<div class='h'>Company Header</div>
<div class='f'>Footer (page numbers unsupported in Kaizen v1.x)</div>
{page}
</body></html>";
var payload = JsonSerializer.Serialize(new { html });
var response = await http.PostAsync(
"http://localhost:8080/html-to-pdf",
new StringContent(payload, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
File.WriteAllBytes("webpage.pdf", await response.Content.ReadAsByteArrayAsync());
}
}
Imports System.IO
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
Dim page As String = Await http.GetStringAsync("https://example.com")
Dim html As String = $"<!doctype html><html><head><style>
@page {{margin: 20mm;}}
.h {{position: fixed; top: -15mm; left: 0; right: 0; text-align: center;}}
.f {{position: fixed; bottom: -15mm; left: 0; right: 0; text-align: center;}}
</style></head><body>
<div class='h'>Company Header</div>
<div class='f'>Footer (page numbers unsupported in Kaizen v1.x)</div>
{page}
</body></html>"
Dim payload As String = JsonSerializer.Serialize(New With {Key .html = html})
Dim response As HttpResponseMessage = Await http.PostAsync(
"http://localhost:8080/html-to-pdf",
New StringContent(payload, Encoding.UTF8, "application/json"))
response.EnsureSuccessStatusCode()
File.WriteAllBytes("webpage.pdf", Await response.Content.ReadAsByteArrayAsync())
End Using
End Function
End Module
Nach (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader.CenterText = "Company Header";
renderer.RenderingOptions.TextFooter.CenterText = "Page {page} of {total-pages}";
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader.CenterText = "Company Header";
renderer.RenderingOptions.TextFooter.CenterText = "Page {page} of {total-pages}";
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader.CenterText = "Company Header"
renderer.RenderingOptions.TextFooter.CenterText = "Page {page} of {total-pages}"
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
RenderUrlAsPdf() ruft die URL direkt ab und rendert sie — kein clientseitiger Seitenabruf — und die simulierten fest verankerten Divs werden ersetzt durch TextHeader / TextFooter Zonen. Seitennummern werden über die {page}und {total-pages}Platzhalter erzeugt, die Kaizen v1.x nicht bietet. Erfahren Sie mehr über URL zu PDF Konvertierung und Kopf- und Fußzeilen.
Kritische Hinweise zur Migration
Lizenz lebt im Code, nicht im Container
Die Lizenz von Kaizen wird über die KAIZEN_PDF_LICENSE-Umgebungsvariable auf dem Docker-Container konfiguriert. Die Lizenz von IronPDF ist eine statische Eigenschaft, die einmal beim Start der Anwendung gesetzt wird:
// DELETE the Kaizen container env var:
// docker run ... -e KAIZEN_PDF_LICENSE=... kaizenio.azurecr.io/html-to-pdf
// IronPDF: set once at startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
// DELETE the Kaizen container env var:
// docker run ... -e KAIZEN_PDF_LICENSE=... kaizenio.azurecr.io/html-to-pdf
// IronPDF: set once at startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
' DELETE the Kaizen container env var:
' docker run ... -e KAIZEN_PDF_LICENSE=... kaizenio.azurecr.io/html-to-pdf
' IronPDF: set once at startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim renderer As New ChromePdfRenderer()
Platzhaltersyntax
Wenn Sie zuvor Zeichenketten in das HTML-Subsystem eingefügt haben, bevor Sie es abgeschickt haben, wechseln Sie zu den Renderzeit-Platzhaltern von IronPDF:
{page}(unverändert){total}→{total-pages}{title}→{html-title}{date}→{date}(unverändert)
Rückgabetyp ändern
Kaizen gibt rohe Bytes über HTTP zurück.IronPDF gibt einen PdfDocument zurück:
// Kaizen.io returns byte[] via HTTP
byte[] pdfBytes = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes("output.pdf", pdfBytes);
//IronPDF returns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf"); // Direct save
byte[] bytes = pdf.BinaryData; // Or get bytes if needed
// Kaizen.io returns byte[] via HTTP
byte[] pdfBytes = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes("output.pdf", pdfBytes);
//IronPDF returns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf"); // Direct save
byte[] bytes = pdf.BinaryData; // Or get bytes if needed
Imports System.IO
' Kaizen.io returns Byte() via HTTP
Dim pdfBytes As Byte() = Await response.Content.ReadAsByteArrayAsync()
File.WriteAllBytes("output.pdf", pdfBytes)
' IronPDF returns PdfDocument
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf") ' Direct save
Dim bytes As Byte() = pdf.BinaryData ' Or get bytes if needed
Löschen Sie die HTTP-Verbindungen
Sobald der Renderer in Prozess ist, verschwindet der unterstützende Code:
// DELETE all of:
// - HttpClient lifetime management
// - JSON serialization of { html }
// - response.EnsureSuccessStatusCode() / status-code branches
// - "container unreachable" retry/backoff
// - ReadAsByteArrayAsync()
// Replaced with a single in-process call:
var pdf = renderer.RenderHtmlAsPdf(html);
// DELETE all of:
// - HttpClient lifetime management
// - JSON serialization of { html }
// - response.EnsureSuccessStatusCode() / status-code branches
// - "container unreachable" retry/backoff
// - ReadAsByteArrayAsync()
// Replaced with a single in-process call:
var pdf = renderer.RenderHtmlAsPdf(html);
Fehlerbehebung
Problem 1: Keine HtmlToPdfConverter-Klasse
Problem: Es gibt keine HtmlToPdfConverter Klasse, die ausgetauscht werden kann — Kaizen hat überhaupt kein .NET SDK.
Lösung: Die Migration erfolgt von HttpClient POSTs gegen den Container zu ChromePdfRenderer:
// Kaizen.io: hand-rolled HTTP
using var http = new HttpClient();
var response = await http.PostAsync("http://localhost:8080/html-to-pdf", content);
// IronPDF: in-process renderer
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Kaizen.io: hand-rolled HTTP
using var http = new HttpClient();
var response = await http.PostAsync("http://localhost:8080/html-to-pdf", content);
// IronPDF: in-process renderer
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
Imports System.Net.Http
Imports IronPdf
' Kaizen.io: hand-rolled HTTP
Using http As New HttpClient()
Dim response = Await http.PostAsync("http://localhost:8080/html-to-pdf", content)
End Using
' IronPDF: in-process renderer
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
Problem 2: Wohin ging das Optionsobjekt?
Problem: Kaizen v1.x hat keinen ConversionOptions — das Seitenlayout war Inline-@page CSS, Kopf-/Fußzeilen waren fest verankerte Divs.
Lösung: Verschieben Sie diese Konfiguration zu RenderingOptions auf dem Renderer:
// Before: <style>@page { size: A4 portrait; margin: 20mm; }</style>
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
// Before: <style>@page { size: A4 portrait; margin: 20mm; }</style>
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
' Before: <style>@page { size: A4 portrait; margin: 20mm; }</style>
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
Problem 3: Seitenzahlen werden nicht gerendert
Problem: Kaizen v1.x hat keine {page}/ {total}Platzhalterunterstützung, sodass jeder vor der Migration vorhandene "Seite X von Y"-Fußzeile entweder fehlte oder statischer Text war.
Lösung: Verwenden Sie die Kopf-/Fußzeilen-Platzhalter von IronPDF:
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}"
};
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "Page {page} of {total-pages}"
}
Wenn Sie zuvor {total}in Ihrem eigenen Code vor dem POSTing manuell ersetzt haben, entfernen Sie diesen Ersatz —IronPDF löst {total-pages}zur Renderzeit auf.
Problem 4: Fehler bei der Verbindung mit dem Container
Problem: Codepfade, die "Container nicht erreichbar" / Port-8080-Fehler behandeln.
Lösung:IronPDF läuft innerhalb des Prozesses — es gibt keinen Endpunkt, zu dem man sich verbinden könnte. Löschen Sie die Fehlerbehandlung bei der Verbindungsherstellung.
Ausgabe 5: Erstes Rendering langsam
Problem: Die erste PDF-Generierung dauert 1-3 Sekunden.
Lösung:IronPDF initialisiert Chromium bei der ersten Verwendung. Aufwärmen beim Starten der Anwendung:
// In Program.cs or Startup.cs:
new ChromePdfRenderer().RenderHtmlAsPdf("<html></html>");
// In Program.cs or Startup.cs:
new ChromePdfRenderer().RenderHtmlAsPdf("<html></html>");
' In Program.vb or Startup.vb:
Call New ChromePdfRenderer().RenderHtmlAsPdf("<html></html>")
Migrations-Checkliste
Vor der Migration
- Lokalisieren Sie jede Kaizen-Aufrufstelle (Suchen Sie nach
html-to-pdf,KAIZEN_PDF_LICENSE,kaizenio.azurecr.io,localhost:8080) - Dokumentieren Sie Inline-
@pageCSS, das für Größe, Ausrichtung, Rändern verwendet wird - Dokumentieren Sie gefälschte Kopf-/Fußzeilen-Div-Elemente (fest positioniert mit negativen Versätzen)
- Listen Sie jede clientseitige Platzhaltersubstitution auf (
html.Replace("{page}", ...)usw.) - Beachten Sie den Container-Lebenszyklus: pull, run, restart, Lizenz-Umgebungsvariablen -IronPDF-Lizenzschlüssel erhalten
Container-Abbau
- Stoppen und entfernen Sie den laufenden Kaizen-Container (
docker stop kaizen-pdf && docker rm kaizen-pdf) - Entfernen Sie Kaizen-Pull-/Run-Schritte aus CI/CD
- Entfernen Sie
KAIZEN_PDF_LICENSEaus Geheimnissen/Umgebungen - Installieren Sie das
IronPdfNuGet-Paket (dotnet add package IronPdf)
Code-Änderungen
- Lizenzschlüsselkonfiguration beim Start hinzufügen
- Ersetzen Sie das
HttpClientPOST durchChromePdfRenderer - Verschieben Sie eingebettetes
@pageCSS inRenderingOptionsEigenschaften - Ersetzen Sie JSON POST durch
RenderHtmlAsPdf()/RenderHtmlFileAsPdf()/RenderUrlAsPdf() - Ersetzen Sie gefälschte Kopf-/Fußzeilen-Divs durch
TextHeader/FooteroderHtmlHeader/Footer - Aktualisieren Sie die Platzhaltersyntax (
{total}→{total-pages},{title}→{html-title}) - Ersetzen Sie den
byte[]HTTP-Body durchpdf.BinaryData - Verwenden Sie
pdf.SaveAs()anstelle vonFile.WriteAllBytes() - Löschen Sie die Fehlerbehandlung und das erneute Versuchen/Backoff bei Nicht-Erreichbarkeit des Containers
Testen
- Alle PDF-Generierungspfade testen
- Überprüfen Sie die Kopf-/Fußzeilen-Darstellung und die Seitenzahlen (neue Fähigkeit)
- Validieren Sie Ränder, Seitengröße und Orientierung
- Testen Sie den Offline-Betrieb (kein Container erforderlich)
Nach der Migration
- Bauen Sie die Kaizen-Containerinfrastruktur ab
- Aktualisieren Sie Umgebungsvariablen / Geheimnisse
- Entfernen Sie Überprüfungen der Container-Gesundheit aus Überwachung/Alarmierung
- Dokumentieren Sie die neuen typisierten Ausnahmepatterns

