IRONSOFTWAREHOME
VIDEOS

Benutzerdefiniertes Logging in C# verwenden

Curtis Chau
Curtis Chau
Updated: 19. Juli 2026

Die Migration von fo .NET (FO .NET) zu IronPDF ist ein wichtiges Update für Ihren .NET PDF-Generierungsprozess. Dieser Leitfaden bietet eine unkomplizierte Schritt-für-Schritt-Anleitung, um Ihre Codebasis von veraltetem XSL-FO-Markup auf moderne HTML/CSS-basierte PDF-Generierung umzustellen und dabei die bereits vorhandenen Fähigkeiten Ihres Entwicklerteams zu nutzen.

Warum von fo.net zu IronPDF migrieren

Die fo.net-Herausforderungen

fo.net (FO.NET) ist ein C# Port eines frühen Apache FOP Builds, der XSL-FO-Dokumente in PDF konvertiert. Es ist Apache 2.0-lizenziert, hat aber mehrere Einschränkungen für die aktuelle Entwicklung:

  1. Obsolete Technology: XSL-FO (Extensible Stylesheet Language Formatting Objects) is a W3C specification from 2001; das W3C hat die XSL-FO-Arbeitsgruppe 2013 geschlossen und die Sprache wurde nicht weiterentwickelt.

  2. Komplexe Lernkurve: XSL-FO erfordert eine komplexe XML-basierte Markierung mit spezialisierten Formatierungsobjekten (fo:block, fo:table, fo:page-sequence, etc.).

  3. Keine HTML/CSS-Unterstützung: fo.net kann HTML oder CSS nicht rendern—Sie müssen HTML selbst in XSL-FO transformieren (in der Regel über XSLT).

  4. Verlassen/Nicht gewartet: Das Fonet Paket auf nuget.org wurde zuletzt im April 2011 veröffentlicht (v1.0.0, .NET Framework 2.0). Der Community-Fork Fonet.Standard (.NET Standard 2.0) wurde zuletzt im Mai 2020 veröffentlicht (v1.0.5). Das CodePlex-Repository ist obsolet und GitHub-Forks (prepare/FO.NET, nholik/FO.Net, hahmed/Fo.Net) sind inaktiv.

  5. Praktisch nur für Windows: Der Legacy-Build von Fonet hängt von System.Drawing (GDI+) APIs ab, die es effektiv auf Windows beschränken.

  6. Begrenzte moderne Funktionen: Keine JavaScript-Engine, kein CSS3 (Flexbox/Grid), keine moderne Webschriftladen.

  7. Keine URL-Darstellung: fo .NET kann Webseiten nicht direkt darstellen – erfordert eine manuelle HTML-zu-XSL-FO-Konvertierung.

Vergleich zwischen fo.net und IronPDF

Aspektfo.net (FO.NET)IronPDF
EingabeformatXSL-FO (veraltetes XML)HTML/CSS (moderne Webstandards)
LernkurveSteep (XSL-FO-Kenntnisse)Sanft (HTML/CSS-Kenntnisse)
WartungAufgegeben (letzte Veröffentlichung Mai 2020)Aktiv gepflegt
Plattform-UnterstützungNur für WindowsPlattformübergreifend (.NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+)
CSS-UnterstützungNoneVollständiges CSS3 (Flexbox, Grid)
JavaScriptNoneVolle JavaScript-Unterstützung
URL-RenderingNicht unterstütztEingebaut
Moderne MerkmaleBeschränktKopfzeilen, Fußzeilen, Wasserzeichen, Sicherheit
DokumentationVeraltetAusführliche Anleitungen

Warum der Wechsel Sinn macht

fo.net wurde entwickelt, als erwartet wurde, dass XSL-FO ein Standard für die Dokumentenformatierung werden würde. Diese Erwartung hat sich nicht erfüllt. HTML/CSS wurde das universelle Dokumentenformat, während XSL-FO eine Nischen-Fähigkeit blieb — die meisten XSL-FO-Ressourcen stammen aus 2005–2010, was die Wartung zunehmend erschwert.

IronPDF ermöglicht es Ihnen, die Fähigkeiten zu nutzen, die Sie bereits haben, um professionelle PDFs auf modernen .NET-Plattformen zu erstellen.


Bevor Sie beginnen

Voraussetzungen

  1. **.NET Umgebung:**IronPDF unterstützt .NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+
  2. NuGet -Zugriff: Stellen Sie sicher, dass Sie Pakete von NuGet installieren können.
  3. Lizenzschlüssel: Ihren IronPDF Lizenzschlüssel für die produktive Nutzung erhalten Sie unter IronPDF.

Sichern Sie Ihr Projekt

# Create a backup branch
git checkout -b pre-ironpdf-migration
git add .
git commit -m "Backup before fo.net to IronPDF migration"
SHELL

Alle fo.net-Nutzungen identifizieren

# Find all fo.net references
grep -r "FonetDriver\|Fonet\|\.fo\"\|xsl-region" --include="*.cs" --include="*.csproj" .

# Find all XSL-FO template files
find . -name "*.fo" -o -name "*.xslfo" -o -name "*xsl-fo*"
SHELL

Dokumentieren Sie Ihre XSL-FO-Vorlagen

Katalogisieren Sie vor der Migration alle XSL-FO-Dateien und notieren Sie sie:

  • Seitenabmessungen und Ränder
  • Verwendete Schriftarten
  • Tabellen und ihre Strukturen
  • Kopf- und Fußzeilen (fo:static-content)
  • Seitennummerierungsmuster
  • Bildreferenzen

Schnellstart Migration

Schritt 1: NuGet-Pakete aktualisieren

# Remove fo.net package
dotnet remove package Fonet
dotnet remove package FO.NET

# Install IronPDF
dotnet add package IronPdf
SHELL

Schritt 2: Namespaces aktualisieren

// Before (fo.net)
using Fonet;
using Fonet.Render.Pdf;
using System.Xml;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;

Schritt 3:IronPDF initialisieren

// Set license key at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

Schritt 4: Grundlegendes Konvertierungsmuster

// Before (fo.net with XSL-FO)
FonetDriver driver = FonetDriver.Make();
using (FileStream output = new FileStream("output.pdf", FileMode.Create))
{
    driver.Render(new StringReader(xslFoContent), output);
}

// After (IronPDF with HTML)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");

Komplette API-Referenz

Namensraum-Zuordnung

fo.net NamespaceIronPDF-Äquivalent
FonetIronPdf
Fonet.Render.PdfIronPdf
Fonet.LayoutNicht anwendbar
Fonet.FoNicht anwendbar
Fonet.ImageIronPdf

FonetDriver zu ChromePdfRenderer

FonetDriver-MethodeIronPDF-Äquivalent
FonetDriver.Make()new ChromePdfRenderer()
driver.Render(inputStream, outputStream)renderer.RenderHtmlAsPdf(html)
driver.Render(inputFile, outputStream)renderer.RenderHtmlFileAsPdf(path)
driver.BaseDirectoryRenderingOptions.BaseUrl
driver.OnError += handlerTry/catch um rendern

RenderingOptions (PDF-Konfiguration)

fo.net (XSL-FO-Attribute)IronPDF RenderingOptionen
page-heightPaperSize oder SetCustomPaperSize()
page-widthPaperSize
margin-topMarginTop
margin-bottomMarginBottom
margin-leftMarginLeft
margin-rightMarginRight
reference-orientationPaperOrientation

XSL-FO zu HTML Konvertierungsanleitung

XSL-FO-Elemente in HTML/CSS

Die grundlegende Veränderung bei dieser fo.net-Migration ist die Umwandlung von XSL-FO-Elementen in ihre HTML-Entsprechungen:

XSL-FO-ElementHTML/CSS-Äquivalent
<fo:root><html>
<fo:layout-master-set>CSS @page Regel
<fo:simple-page-master>CSS @page
<fo:page-sequence><body> oder <div>
<fo:flow><main> oder <div>
<fo:static-content>HtmlHeaderFooter
<fo:block><p>, <div>, <h1>-<h6>
<fo:inline><span>
<fo:table><table>
<fo:table-row><tr>
<fo:table-cell><td>, <th>
<fo:list-block><ul>, <ol>
<fo:list-item><li>
<fo:external-graphic><img>
<fo:page-number>{page} Platzhalter
<fo:page-number-citation>{total-pages}
<fo:basic-link><a href>

XSL-FO-Eigenschaften in CSS

XSL-FO-EigenschaftCSS-ÄquivalentBeispiel
font-familyfont-familyGleiche Syntax
font-sizefont-sizeGleiche Syntax
font-weightfont-weightbold, normal, 700
text-aligntext-alignleft, center, right, justify
colorcolorHex, RGB, Namen
background-colorbackground-colorGleiche Syntax
space-beforemargin-topVor dem Element
space-aftermargin-bottomNach Element
start-indentmargin-leftLinker Einzug
keep-togetherpage-break-inside: avoidBrüche verhindern
break-before="page"page-break-before: alwaysSeitenumbruch erzwingen

Beispiele für Code

Beispiel 1: Grundlegendes HTML zu PDF

Vor (fo.net mit XSL-FO):

// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;

class Program
{
    static void Main()
    {
        // fo.net requires XSL-FO format, not HTML
        // First convert HTML to XSL-FO (manual process)
        string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
            <fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
                <fo:layout-master-set>
                    <fo:simple-page-master master-name='page'>
                        <fo:region-body/>
                    </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference='page'>
                    <fo:flow flow-name='xsl-region-body'>
                        <fo:block>Hello World</fo:block>
                    </fo:flow>
                </fo:page-sequence>
            </fo:root>";
        
        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("output.pdf", FileMode.Create));
    }
}

Nachher (IronPDF mit HTML):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<h1>Hello World</h1><p>This is HTML content.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}

Der IronPDF-Ansatz reduziert 25+ Zeilen XSL-FO-Markup auf nur 4 Zeilen sauberen C#-Code. Weitere Optionen für die Umwandlung von HTML in PDF finden Sie in der IronPDF HTML to PDF Dokumentation.

Beispiel 2: PDF mit benutzerdefinierten Einstellungen

Vor (fo.net mit XSL-FO):

// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;

class Program
{
    static void Main()
    {
        // fo.net settings are configured in XSL-FO markup
        string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
            <fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
                <fo:layout-master-set>
                    <fo:simple-page-master master-name='A4' 
                        page-height='297mm' page-width='210mm'
                        margin-top='20mm' margin-bottom='20mm'
                        margin-left='25mm' margin-right='25mm'>
                        <fo:region-body/>
                    </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference='A4'>
                    <fo:flow flow-name='xsl-region-body'>
                        <fo:block font-size='14pt'>Custom PDF</fo:block>
                    </fo:flow>
                </fo:page-sequence>
            </fo:root>";
        
        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("custom.pdf", FileMode.Create));
    }
}

Nachher (IronPDF mit HTML):

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 20;
        renderer.RenderingOptions.MarginBottom = 20;
        renderer.RenderingOptions.MarginLeft = 25;
        renderer.RenderingOptions.MarginRight = 25;
        
        string html = "<h1 style='font-size:14pt'>Custom PDF</h1>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}

IronPDF bietet programmatische Rendering-Optionen anstelle der Einbettung der Konfiguration in XML-Markup.

Beispiel 3: URL zu PDF

Vor (fo.net - nicht unterstützt):

// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;

class Program
{
    static void Main()
    {
        // fo.net does not support URL rendering directly
        // Must manually download, convert HTML to XSL-FO, then render
        string url = "https://example.com";
        string html = new WebClient().DownloadString(url);
        
        // Manual conversion from HTML to XSL-FO required (complex)
        string xslFo = ConvertHtmlToXslFo(html); // Not built-in
        
        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("webpage.pdf", FileMode.Create));
    }
    
    static string ConvertHtmlToXslFo(string html)
    {
        // Custom implementation required - extremely complex
        throw new System.NotImplementedException();
    }
}

Nach (IronPDF - integrierte Unterstützung):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("webpage.pdf");
    }
}

Die URL-zu-PDF-Konvertierung ist eines der praktischen Vorteile dieser fo.net-Migration:IronPDF bearbeitet es nativ mit der Ausführung von JavaScript. Erfahren Sie mehr über die URL in PDF Konvertierung.

Beispiel 4: Kopf- und Fußzeilen

Vor (fo.net mit XSL-FO):

<fo:static-content flow-name="xsl-region-before">
    <fo:block text-align="center" font-size="10pt">
        Company Name - Confidential
    </fo:block>
</fo:static-content>

<fo:static-content flow-name="xsl-region-after">
    <fo:block text-align="right" font-size="10pt">
        Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/>
    </fo:block>
</fo:static-content>
XML

Nach (IronPDF):

renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:center; font-size:10pt;'>Company Name - Confidential</div>",
    DrawDividerLine = true
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:right; font-size:10pt;'>Page {page} of {total-pages}</div>",
    DrawDividerLine = true
};

IronPDF ersetzt komplexe XSL-FO-Bereichsdefinitionen durch einfache HTML-Kopf- und -Fußzeilen.

Beispiel 5: PDF-Sicherheit

Vor (fo.net):

// fo.net has very limited PDF security options
// Must use post-processing with another library

Nach (IronPDF):

using IronPdf;

public byte[] GenerateSecurePdf(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = renderer.RenderHtmlAsPdf(html);

    // Set metadata
    pdf.MetaData.Title = "Confidential Report";
    pdf.MetaData.Author = "Company Name";

    // Password protection
    pdf.SecuritySettings.OwnerPassword = "owner123";
    pdf.SecuritySettings.UserPassword = "user456";

    // Restrict permissions
    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
    pdf.SecuritySettings.AllowUserEdits = IronPdf.Security.PdfEditSecurity.NoEdit;

    return pdf.BinaryData;
}

Erwägungen zur Leistung

Wiederverwendung von ChromePdfRenderer

Für optimale Leistung während Ihrer fo.net-Migration, wiederverwenden Sie die ChromePdfRenderer Instanz:

// GOOD - Reuse the renderer
public class PdfService
{
    private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

    public byte[] Generate(string html) => _renderer.RenderHtmlAsPdf(html).BinaryData;
}

// BAD - Creating new instance each time
public byte[] GenerateBad(string html)
{
    var renderer = new ChromePdfRenderer();  // Wasteful
    return renderer.RenderHtmlAsPdf(html).BinaryData;
}

Helfer bei der Einheitenumwandlung

fo.net XSL-FO verwendet verschiedene Einheiten.IronPDF verwendet Millimeter für die Ränder. Hier ist eine Hilfsklasse:

public static class UnitConverter
{
    public static double InchesToMm(double inches) => inches * 25.4;
    public static double PointsToMm(double points) => points * 0.352778;
    public static double PicasToMm(double picas) => picas * 4.233;
    public static double CmToMm(double cm) => cm * 10;
}

// Usage
renderer.RenderingOptions.MarginTop = UnitConverter.InchesToMm(1);  // 1 inch

Fehlerbehebung

Problem 1: Unterschiede in der Seitengröße

Problem: Die PDF-Seitengröße sieht nach der .NET Migration anders aus.

Lösung: XSL-FO-Seitendimensionen korrekt zuordnen:

// XSL-FO: page-height='11in' page-width='8.5in' (Letter)
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;

// XSL-FO: page-height='297mm' page-width='210mm' (A4)
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

// Custom size (in mm)
renderer.RenderingOptions.SetCustomPaperSize(210, 297);

Ausgabe 2: fo:block zu HTML Mapping

Problem: Nicht sicher, was aus <fo:block> werden sollte.

Lösung: Verwenden Sie geeignetes semantisches HTML:

  • Überschriften: <h1> bis <h6>
  • Absätze: <p>
  • Allgemeine Container: <div>
  • Inline-Text: <span>

Problem 3: Nicht übereinstimmende Schriftarten

Problem: Die Schriftarten sehen anders aus als in der .NET Ausgabe.

Lösung: Webfonts verwenden oder Systemfonts in CSS angeben:

<style>
    @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
    body { font-family: 'Roboto', Arial, sans-serif; }
</style>
HTML

Ausgabe 4: Nicht funktionierende Seitenzahlen

Problem: <fo:page-number/> funktioniert nicht.

Lösung: Verwenden Sie IronPDF Platzhalter in Kopf- und Fußzeilen:

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:center;'>Page {page} of {total-pages}</div>",
    MaxHeight = 15  // mm
};

Migrations-Checkliste

Vor der Migration

  • Katalogisieren Sie alle XSL-FO-Vorlagendateien (.fo, .xslfo)
  • Dokumentseitenabmessungen und -ränder verwendet
  • Notieren Sie sich Kopf-/Fußzeilenkonfigurationen (fo:static-content)
  • Tabellenstrukturen und -styling identifizieren
  • Projekt in der Versionskontrolle sichern -IronPDF-Lizenzschlüssel erhalten

Paket-Migration

  • Entfernen Sie Fonet oder FO.NET Paket: dotnet remove package Fonet
  • Installieren Sie das IronPdf Paket: dotnet add package IronPdf
  • Aktualisieren Sie die Namespace-Importe von Fonet zu IronPdf -IronPDF-Lizenzschlüssel beim Start festlegen

Code-Migration

  • Ersetzen Sie FonetDriver.Make() durch new ChromePdfRenderer()
  • Ersetzen Sie driver.Render() durch renderer.RenderHtmlAsPdf()
  • Aktualisieren Sie die Dateiausgabe von Streams zu pdf.SaveAs()
  • Ersetzen Sie Fehlerbehandlungsroutinen durch try/catch
  • Konvertieren Sie fo:static-content zu HtmlHeaderFooter
  • Ersetzen Sie <fo:page-number/> durch {page} Platzhalter

Testen

  • Vergleichen Sie das Erscheinungsbild der Ausgabe mit dem ursprünglichen fo .NET PDF.
  • Seitenabmessungen und Ränder überprüfen
  • Überprüfen Sie Kopf- und Fußzeilen
  • Seitenzahlen überprüfen
  • Testtabellenrendering
  • Überprüfen Sie das Laden des Bildes

Nach der Migration

  • Löschen Sie .fo und .xslfo Vorlagendateien
  • Entfernen Sie fo.net-bezogenen Code und Hilfsprogramme.
  • Dokumentation aktualisieren

Für eine tiefere Abdeckung der oben verwendeten IronPDF-Funktionalität lesen Sie die IronPDF API-Referenz.

Hinweis:: FO.NET, Fonet, und Apache FOP sind Marken ihrer jeweiligen Eigentümer. Diese Seite ist nicht mit dem FO.NET-Projekt oder der Apache Software Foundation verbunden, gebilligt oder gesponsert. Alle Produktnamen, Logos und Marken sind Eigentum ihrer jeweiligen Eigentümer. Vergleiche dienen nur zu Informationszwecken und spiegeln öffentlich zugängliche Informationen zum Zeitpunkt des Schreibens wider.
Curtis Chau
Technischer Autor

Curtis Chau hat einen Bachelor-Abschluss in Informatik von der Carleton University und ist spezialisiert auf Frontend-Entwicklung mit Expertise in Node.js, TypeScript, JavaScript und React. Leidenschaftlich widmet er sich der Erstellung intuitiver und ästhetisch ansprechender Benutzerschnittstellen und arbeitet gerne mit modernen Frameworks sowie der Erstellung gut strukturierter, optisch ansprechender Handbücher.

...
Weiterlesen

Verwandte Artikel

Key in blue circle

Holen Sie sich sofort Ihren kostenlosen 30-Tage-Testschlüssel.

Your trial license will be sent to your email address

Keine Einschränkungen. 100 % freigeschaltet. Keine Kreditkarte.

bullet_checkedIhr Testlizenzschlüssel wurde Ihnen per E-Mail gesendet.Keine Einschränkungen. 100 % freigeschaltet. Keine Kreditkarte.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Buchen Sie Ihre kostenlose Live-Demo
Booking Badge

Von Millionen von Ingenieur*innen weltweit vertraut

Kundenlogos von Iron Software
Erhalten Sie Ihre unverbindliche Beratung
Füllen Sie das Formular unten aus oder senden Sie eine E-Mail an sales@ironsoftware.com
Ihre Daten werden immer vertraulich behandelt.
Von Millionen von Ingenieur*innen weltweit vertraut
Kundenlogos von Iron Software
Erhalten Sie sofort Ihren kostenlosen 30-Tage-Testschlüssel.
Ihr Testlizenzschlüssel wurde Ihnen per E-Mail gesendet.