Dokumentation & erste Schritte
Wie Validator, Creator und Reader in eine eigene .NET-Anwendung eingebunden werden – vom NuGet-Paket über den ersten funktionierenden Aufruf bis zu Rückgabewerten und Fehlerbehandlung.
- .NET Framework 4.8
- .NET 8
- .NET 10
- ZUGFeRD 2.5.2 / Factur-X 1.09.2
- XRechnung 3.0 (CII & UBL)
Schnellstart
In drei Schritten von der PDF zur Konformitätsaussage. Das folgende Beispiel entspricht dem tatsächlichen Ablauf, den auch die Live-Demo verwendet.
- Paket
Facturexa.ZugferdValidatorper NuGet hinzufügen. Die amtlichen Regelwerke (XML-Schema und Schematron) werden mitgeliefert und automatisch gefunden. - Einmalig beim Programmstart den Lizenzschlüssel registrieren. Sie erhalten ihn per E-Mail und finden ihn jederzeit im Kundenkonto.
- Pro Rechnung die PDF (oder die XML) mit einem Aufruf validieren.
using Facturexa.ZugferdValidator;
// Einmalig beim Programmstart: Lizenzschlüssel registrieren.
ZugferdValidatorLicense.RegisterLicense("…");
// Rechnungs-PDF prüfen: PDF-Hülle, XML-Schema und offizielle Schematron in einem Aufruf.
var ergebnis = ZugferdValidator.Validate("rechnung.pdf", "RE-2026-0001");
Console.WriteLine(ergebnis.IsValid ? "Gültig" : "Nicht konform");
Der vollständige Ablauf mit Fehlerbehandlung folgt im Abschnitt Validator.
Installation & Voraussetzungen
Jede Bibliothek ist ein eigenständiges NuGet-Paket und kann einzeln eingebunden werden.
dotnet add package Facturexa.ZugferdValidator
Install-Package Facturexa.ZugferdValidator
dotnet add package Facturexa.ZugferdCreator
Install-Package Facturexa.ZugferdCreator
dotnet add package Facturexa.ZugferdReader
Install-Package Facturexa.ZugferdReader
Voraussetzungen
- .NET 10, .NET 8 oder .NET Framework 4.8
- Windows, Linux oder macOS
- Validator: Ordner
Official Schematron\neben der Anwendung (kopiert das Paket automatisch) - Validator: kein Trimming (
PublishTrimmed) und kein Native AOT
Ausprobieren ohne Code
Die Live-Demo zeigt den Validator direkt im Browser, ganz ohne Integration in eigenen Code.
Bereitstellung der Regelwerke (Validator)
- Offline-Betrieb: Alle Regelwerke (XML-Schema, Schematron, Codelisten) sind im Paket enthalten. Zur Laufzeit ist keine Internetverbindung nötig, und der Validator ruft keinen externen Dienst auf – auch die Lizenzprüfung erfolgt lokal. Eine Firewall-Freigabe ist nicht erforderlich.
- Das Paket kopiert
Official Schematron\(Schematron-Regelwerke und unterXSD\das XML-Schema) beim Build und beim Veröffentlichen automatisch neben Ihre Anwendung – auch bei klassischem ASP.NET (unterbin\), Single-File, ClickOnce und wenn Sie den Validator über eine eigene Bibliothek oder ein eigenes NuGet-Paket einbinden. - Nach einem Downgrade des Pakets die Lösung einmal bereinigen bzw. neu erstellen, damit die älteren Regelwerksdateien die neueren im Ausgabeordner ersetzen.
- Ordner selbst bereitstellen:
<FacturexaContentAutoCopy>false</FacturexaContentAutoCopy>im Projekt setzen, bei PackageReference zusätzlichExcludeAssets="contentFiles"am Paketverweis, undSchematronChecker.SchematronDirectoryauf den Ordner setzen.
Profile & Versionen
ZUGFeRD kennt mehrere Profile mit unterschiedlicher Informationsdichte. Welche der Validator prüft und der Creator erzeugt, zeigt die folgende Übersicht.
| Profil | Beschreibung | Validator | Creator |
|---|---|---|---|
| MINIMUM | Kopfdaten, kein eigenständig gültiges E-Rechnungsformat | ✔ Ja | ✔ Ja |
| BASIC WL | Kopfdaten ohne Rechnungspositionen | ✔ Ja | ✔ Ja |
| BASIC | Kerninformationen inkl. Rechnungspositionen | ✔ Ja | ✔ Ja |
| EN 16931 / COMFORT | Europäischer Kernstandard – gültiges E-Rechnungsformat | ✔ Ja | ✔ Ja |
| EXTENDED | Erweiterter Datensatz, ab ZUGFeRD 2.5.2 inkl. Sub-Positionen/Kits & Bündel | ✔ Ja | ✔ Ja |
| XRechnung 3.0 (CIUS) | Deutsche B2G-Kernvariante, zweistufig EN 16931 + CIUS | ✔ Ja (CII + UBL) | ✔ Ja (CII) |
| UBL-Erzeugung | XRechnung als UBL statt CII ausgeben | n. v. (Prüfung erfolgt bereits) | Roadmap |
Version
Der Creator erzeugt immer nach dem aktuellen Stand: ZUGFeRD 2.5.2 / Factur-X 1.09.2
(gültig ab 01.09.2026), inklusive der EXTENDED-Sub-Positionen für Kits und Bündel.
Eine Version wählen Sie beim Save(…) nicht aus – neue
Spezifikationen kommen mit einer neuen Paketversion.
Welchen Stand die eingebundene DLL umsetzt, lässt sich zur Laufzeit abfragen:
ZugferdCreatorInfo.SupportedSpecification.
Validator: eine PDF prüfen
Den Lizenzschlüssel registrieren Sie einmal beim Programmstart. Die amtlichen Regelwerke findet der
Validator automatisch neben der DLL (bei klassischem ASP.NET unter bin\); danach genügt
ein Aufruf pro Prüfung. Übergeben Sie die komplette PDF: Der Validator liest die eingebettete XML selbst,
prüft die PDF-Hülle (PDF/A-3, Factur-X-Metadaten) und danach die XML gegen das XML-Schema und die
offizielle Schematron. Eine reine XML-Datei geht genauso – erkannt wird am Inhalt, nicht an der Endung.
IsValid ist true, wenn keine Stufe einen Fehler meldet; IsPdfValid und
IsSchemaValid liefern die Teilurteile.
using Facturexa.ZugferdValidator;
// Einmalig beim Programmstart.
ZugferdValidatorLicense.RegisterLicense("…");
// PDF oder XML: PDF-Hülle, XML-Schema und offizielle Schematron in einem Aufruf.
var ergebnis = ZugferdValidator.Validate("rechnung.pdf", "RE-2026-0001");
Console.WriteLine(ergebnis.IsValid ? "Gültig" : "Nicht konform");
Console.WriteLine($"PDF-Hülle: {ergebnis.IsPdfValid}"); // null bei reiner XML
Console.WriteLine($"Regelwerk: {ergebnis.SchematronRuleSet}");
foreach (var fehler in ergebnis.Errors)
Console.WriteLine($"{fehler.Stage}: {fehler}"); // z.B. "Schematron: BR-CO-15 (BT-112): ..."
Weiterführend: Produktseite Validator · Live-Demo testen
Creator: eine Rechnung erzeugen
Lizenzschlüssel einmal beim Programmstart registrieren, dann Rechnungskopf, Parteien, Positionen und Summen setzen, Version und Profil wählen, speichern. Aktuell wird CII ausgegeben (UBL ist auf der Roadmap).
using Facturexa.ZugferdCreator;
// Einmalig beim Programmstart.
ZugferdCreatorLicense.RegisterLicense("…");
var rechnung = new EInvoice
{
InvoiceNumber = "RE-2026-0001",
InvoiceDate = DateTime.Today
};
rechnung.SetSellerTradeParty("Muster GmbH", "12345", "Berlin", "Musterstraße 1", CountryID.DE);
rechnung.AddSellerSpecifiedTaxRegistration("DE123456789", TaxRegistrationSchemeID.VA);
rechnung.SetBuyerTradeParty("Kunde AG", "54321", "Hamburg", "Kundenweg 2", CountryID.DE);
rechnung.AddIncludedSupplyChainTradeLineItem(
name: "Beratungsleistung", netUnitPrice: 100.00m, unitCode: UnitCode.C62,
billedQuantity: 3m, lineTotalAmount: 300.00m, taxPercent: 19m);
rechnung.AddApplicableTradeTax(300.00m, 19m, 57.00m, TaxTypeCode.VAT, TaxCategoryCode.S);
rechnung.LineTotalAmount = 300.00m;
rechnung.TaxBasisAmount = 300.00m;
rechnung.TaxTotalAmount = 57.00m;
rechnung.GrandTotalAmount = 357.00m;
rechnung.DuePayableAmount = 357.00m;
using var xmlStream = new MemoryStream();
rechnung.Save(xmlStream, InvoiceProfile.Comfort);
Weiterführend: Produktseite Creator · Live-Demo testen
Reader: eine Rechnung auslesen
Der Reader liest eine Rechnung – als blanke XML (CII oder UBL) oder als PDF mit eingebetteter XML; das Format wird automatisch erkannt – und gibt die Felder als Objekt zurück. Optional rendert er daraus eine lesbare PDF-Ansicht.
using Facturexa.ZugferdReader;
// PDF oder XML einlesen – der Dateiname hilft bei der Formaterkennung.
using var stream = File.OpenRead("rechnung.pdf");
var rechnung = ZugferdReader.Read(stream, "rechnung.pdf");
Console.WriteLine(rechnung.InvoiceNumber);
Console.WriteLine(rechnung.InvoiceDate?.ToString("dd.MM.yyyy"));
Console.WriteLine(rechnung.Seller?.Name);
Console.WriteLine($"{rechnung.LineItems.Count} Position(en), {rechnung.GrandTotalAmount:N2} {rechnung.CurrencyCode}");
// Optional: lesbare PDF-Ansicht der Rechnung erzeugen.
byte[] ansichtPdf = ZugferdReader.CreatePdf(rechnung);
File.WriteAllBytes("rechnung-ansicht.pdf", ansichtPdf);
Weiterführend: Produktseite Reader · Live-Demo testen
Rückgabewerte
Die wichtigsten Felder der Ergebnisobjekte im Überblick.
ZugferdValidationResult – Validator.Validate(…)
| Member | Typ | Bedeutung |
|---|---|---|
IsValid | bool | True, wenn keine Stufe einen Fehler meldet (PDF-Hülle, XML-Schema, offizielle Schematron) und die PDF-Prüfung nicht fehlgeschlagen ist. |
IsPdfValid | bool? | Urteil der PDF-Prüfung; null, wenn eine XML statt einer PDF geprüft wurde. |
IsSchemaValid | bool | True, wenn das XML-Schema (XSD) keinen Fehler meldet. |
PdfCheck | ZugferdPdfCheckResult | Ergebnis der PDF-Prüfung mit Statuszeilen (siehe unten); null bei reiner XML. |
PdfFindings / SchemaFindings / SchematronFindings | List<ValidationFinding> | Befunde einer Prüfstufe; jeder Befund nennt seine Stufe in Stage. |
EmbeddedXml / EmbeddedXmlFileName | byte[] / string | Die geprüfte XML und bei einer PDF der Anhangname, z. B. „factur-x.xml“ – etwa zur Weitergabe an den Reader. |
Errors | List<ValidationFinding> | Blockierende Befunde (Schweregrad Error). |
Warnings | List<ValidationFinding> | Warnungen; verhindern den Versand nicht. |
Findings | List<ValidationFinding> | Alle Befunde ungefiltert. |
SchematronRuleSet | string | Angewandtes amtliches Regelwerk, z. B. „ZUGFeRD 2.5.2 / Factur-X 1.09.2, profile EXTENDED – release date 2026-08-04 (FACTUR-X_EXTENDED.xslt)". Null, wenn das Profil nicht abgedeckt ist oder die Schematron nicht laufen konnte. |
ProfileInfo | InvoiceProfileInfo | Vom Beleg selbst deklarierte Version/Profil (BT-24). |
GetErrorMessages() | List<string> | Fehler als fertige Meldungstexte inkl. Rechnungsnummer. |
ZugferdPdfCheckResult – ZugferdValidationResult.PdfCheck
| Member | Typ | Bedeutung |
|---|---|---|
OverallValid | bool | Gesamturteil der PDF-Prüfung (entspricht IsPdfValid). |
Format | string | PDF/A-Kennung aus den XMP-Metadaten, z. B. „PDFA_3_B“, sonst „unknown“. |
FacturXVersion | string | Factur-X-Version aus den XMP-Metadaten, z. B. „1.0“. |
XmlExtractable / EmbeddingCompliant / FileNameCompliant / XmpCompliant | ZugferdPdfCheckStatus | Statuszeilen: Yes, No oder Unknown. |
Findings | List<ValidationFinding> | Befunde der PDF-Prüfung (PDF-CHECK-01 bis -16, PDF-XML-MISSING). |
Bisherige API: ZugferdPdfReader.ReadZugferdXml(…) und ZugferdPdfValidator.Validate(…) funktionieren bis Version 8.0 weiter, sind seit 7.4.0 aber als veraltet markiert. Übergeben Sie stattdessen die PDF direkt an ZugferdValidator.Validate(…).
InvoiceViewModel – ZugferdReader.Read(…)
| Member | Typ | Bedeutung |
|---|---|---|
InvoiceNumber | string | Rechnungsnummer (BT-1). |
InvoiceDate | DateTime? | Rechnungsdatum (BT-2). |
Seller / Buyer | InvoicePartyViewModel | Verkäufer/Käufer inkl. .Name und Adresse. |
LineItems | List<…> | Rechnungspositionen. |
GrandTotalAmount | decimal? | Bruttogesamtbetrag (BT-112). |
CurrencyCode | string | Währung (BT-5), z. B. „EUR". |
ProfileUrn | string | Profil-URN aus der CustomizationID. |
Fehlerbehandlung & Troubleshooting
Die häufigsten Stolpersteine bei der Integration und ihre Ursache.
| Symptom | Ursache & Lösung |
|---|---|
ZugferdValidatorLicenseException bzw. ZugferdCreatorLicenseException: „No license key found" |
Der Schlüssel wurde nicht registriert. ZugferdValidatorLicense.RegisterLicense("…") bzw. ZugferdCreatorLicense.RegisterLicense("…") einmal beim Programmstart aufrufen, vor der ersten Prüfung bzw. Erzeugung. |
Befund XSD-ERROR: Prüfung gegen das XML-Schema konnte nicht ausgeführt werden |
Die XSD-Dateien (Official Schematron\XSD\) wurden nicht mit ausgeliefert oder der Ordner liegt nicht neben der DLL. Den Ordner Official Schematron\ vollständig deployen oder SchematronChecker.SchematronDirectory einmalig auf seinen Pfad setzen. Eine nicht durchführbare Prüfung wird bewusst als Error gemeldet. |
Befund PDF-XML-MISSING, Meldung „The PDF file contains no attachments“ |
Die PDF enthält keine eingebettete XML – sie ist keine ZUGFeRD-Rechnung. Eine echte Factur-X-/ZUGFeRD-PDF verwenden oder direkt die XML validieren. |
IsValid == false trotz augenscheinlich gültiger Rechnung; Fehler nennt Saxon/Schematron |
Saxon-DLL oder Schematron-Artefakte wurden nicht mit ausgeliefert. Eine nicht durchführbare Prüfung wird bewusst als Error gemeldet. Artefakte deployen. |
Nach Veröffentlichen mit PublishTrimmed: Befund SCHEMATRON-ERROR, Meldung nennt DotNetLocaleHelper |
Die Saxon-Engine verträgt weder Trimming noch Native AOT. Ohne PublishTrimmed veröffentlichen. |
ZugferdReaderException / UnsupportedFormatException |
Die Datei ist weder eine PDF mit eingebetteter XML noch eine XML in CII- oder UBL-Syntax. Ein unterstütztes Format verwenden; den Aufruf von ZugferdReader.Read(…) in try/catch kapseln. |