1. Einführung
Erinnerung: Serialization ist ein Weg, den Zustand eines Objekts als String, Datei oder Stream zu speichern, damit man das Objekt später wiederherstellen (deserialisieren) kann — und man hat wieder ein Objekt mit denselben Daten.
Typische Situation:
1) Du hast ein Objekt, z. B. einen Nutzer mit Name und Alter.
2) Du musst das speichern — über das Netzwerk schicken, in eine Datei schreiben oder z. B. ins JSON-Format.
3) Später ziehst du die Daten aus dem String/der Datei zurück — und bekommst wieder das Objekt!
In C# geht das in wenigen Zeilen. Schauen wir uns an, wie genau.
Unsere Anwendung
Wir entwickeln eine kleine Anwendung "Kontaktmanager". Angenommen, wir haben die Klasse Person, die wir serialisieren wollen.
public class Person
{
// Öffentliche Eigenschaften sind für die Serialization wichtig!
public string Name { get; set; }
public int Age { get; set; }
// Parameterloser Konstruktor ist für XmlSerializer erforderlich
public Person() { }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
Wenn dir diese Syntax noch fremd ist, keine Sorge — im weiteren Kurs werden Klassen und Eigenschaften ausführlich erklärt. Sieh das hier erst mal als Datenmodell für Experimente. Beachte: die öffentlichen Eigenschaften Name und Age sind wichtig für die Serialization, und für XmlSerializer wird ein öffentlicher parameterloser Konstruktor benötigt.
2. JSON-Serialization mit System.Text.Json
Ein einfaches Beispiel
Wie versprochen — hier die JSON-Serialization:
using System;
using System.Text.Json;
Person person = new Person("Alisa", 28);
// Serialization: Objekt in JSON-String umwandeln
string json = JsonSerializer.Serialize(person);
Console.WriteLine("JSON:");
Console.WriteLine(json);
Was wird auf der Konsole stehen?
JSON:
{"Name":"Alisa","Age":28}
Ganz einfach: Objekt → JSON. Das ist die Magie!
Deserialization — alles zurückholen
Jetzt die Gegenrichtung — aus einem JSON-String das Objekt wiederherstellen:
string json = "{\"Name\":\"Bob\",\"Age\":35}";
// Deserialization: Objekt vom Typ Person aus dem JSON-String wiederherstellen
Person restored = JsonSerializer.Deserialize<Person>(json);
Console.WriteLine("Wiederhergestelltes Objekt:");
Console.WriteLine($"Name: {restored.Name}, Alter: {restored.Age}");
Ergebnis:
Wiederhergestelltes Objekt:
Name: Bob, Alter: 35
Beachte: wenn die Datenstruktur nicht übereinstimmt (z. B. eine Eigenschaft fehlt), bleibt das entsprechende Feld mit dem Standardwert (null für Referenztypen, 0 für Zahlen usw.).
3. XML-Serialization/Deserialization mit XmlSerializer
Erster Blick auf XML-Serialization
using System;
using System.IO;
using System.Xml.Serialization;
Person person = new Person("Katja", 22);
// Serializer für den Typ Person erstellen
var serializer = new XmlSerializer(typeof(Person));
// XML in eine Datei schreiben
using (var stream = new FileStream("person.xml", FileMode.Create))
{
serializer.Serialize(stream, person);
// Der Stream wird am Ende des using-Blocks automatisch geschlossen
}
Console.WriteLine("XML-Datei erstellt!");
In der Datei person.xml steht dann ungefähr so etwas:
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Katja</Name>
<Age>22</Age>
</Person>
Wichtiger Punkt:
Für die Serialization in eine Datei verwendet man einen Stream (Stream, z. B. FileStream). Wenn du in einen String serialisieren willst (z. B. zum Versenden über das Netzwerk), nutze StringWriter:
var serializer = new XmlSerializer(typeof(Person));
using (var sw = new StringWriter())
{
serializer.Serialize(sw, person);
string xmlString = sw.ToString();
Console.WriteLine(xmlString);
}
Deserialization aus XML
using (var stream = new FileStream("person.xml", FileMode.Open))
{
// Nicht vergessen, auf den richtigen Typ zu casten!
Person restored = (Person)serializer.Deserialize(stream);
Console.WriteLine($"Name: {restored.Name}, Alter: {restored.Age}");
}
Noch einmal: XmlSerializer verlangt, dass die zu serialisierende Klasse einen öffentlichen parameterlosen Konstruktor hat.
4. Arbeiten mit Dateien und Strings: was wählen?
Im echten Leben kann Serialization direkt in einen String erfolgen (für Netzwerkübertragung/DB-Speicherung) oder in eine Datei (für langfristige Speicherung).
Serialization in einen String (z. B. für API-Übertragung):
- JSON: Verwende JsonSerializer.Serialize(obj).
- XML: Über StringWriter.
Serialization in eine Datei (z. B. für Export/Sicherung):
- JSON: Speichere den String mit normalen Datei-Schreibmethoden.
- XML: Schreibe direkt in einen Stream mit XmlSerializer.
Beispiel: Serialization in Datei und zurück (JSON)
using System.IO;
using System.Text.Json;
Person person = new Person("Tom", 42);
// Serialization in einen String
string json = JsonSerializer.Serialize(person);
// In eine Datei schreiben
File.WriteAllText("contact.json", json);
// Aus der Datei lesen
string readJson = File.ReadAllText("contact.json");
Person restored = JsonSerializer.Deserialize<Person>(readJson);
Console.WriteLine($"{restored.Name}, Alter: {restored.Age}");
5. Vergleich JSON vs XML
Prozessvisualisierung
Damit du nicht durcheinanderkommst, hier die Ablauf-Schema von Serialization und Deserialization:
flowchart LR
A[Objekt] -- serialization --> B[String/Datei/Stream]
B -- deserialization --> C[Objekt]
A -. JSON oder XML .-> B
B -. JSON oder XML .-> C
Stell dir vor, Serialization ist "den Koffer packen", Deserialization ist "zu Hause auspacken".
Vergleichstabelle
| Funktionalität | JSON (System.Text.Json) | XML (XmlSerializer) |
|---|---|---|
| Lesen/Schreiben als String | ++ | + |
| Lesen/Schreiben in Datei | ++ | ++ |
| Benötigt parameterlosen Konstruktor | Nein | Ja |
| Menschenlesbarkeit | ++ | + |
| Striktes Datenschema (Validierung) | - | ++ |
| Flexibilität (Anpassungs-Attribute) | + | ++ |
| Performance | ++ | + |
| Kompatibilität mit dem Internet | ++ | + |
++ — sehr gut, + — okay, - — nicht unterstützt
6. Wie man Serialization in unsere Anwendung einbaut
Angenommen, im "Kontaktmanager" gibt es die Möglichkeit, eine Kontaktliste in eine Datei zu speichern und wiederherzustellen.
Kontext: Wir haben eine Kontaktliste (List<Person>).
List<Person> contacts = new List<Person>
{
new Person("Wasja", 30),
new Person("Petja", 25),
new Person("Masha", 27)
};
// Alle Kontakte speichern — in JSON serialisieren
string jsonContacts = JsonSerializer.Serialize(contacts);
File.WriteAllText("contacts.json", jsonContacts);
// Die Kontaktliste wiederherstellen
string readContactsJson = File.ReadAllText("contacts.json");
List<Person> restored = JsonSerializer.Deserialize<List<Person>>(readContactsJson);
foreach (var c in restored)
{
Console.WriteLine($"{c.Name}, Alter: {c.Age}");
}
Dasselbe geht auch mit XML, aber dort gibt es Besonderheiten. Für die Serialization von Collections mit XmlSerializer umgibt man die Liste häufig mit einer separaten Container-Klasse (Root-Element) — so ist es einfacher, das Format und die Elementnamen zu kontrollieren.
7. Typische Fehler bei Serialization und Deserialization
Fehler Nr.1: Typen-Mismatch bei Serialization/Deserialization.
Du hast List<Person> serialisiert — deserialisieren musst du ebenfalls in List<Person>, nicht in List<object> oder IEnumerable<Person>. Sonst bekommst du eine Exception oder unerwartete Ergebnisse.
Fehler Nr.2: Versuch, nicht-öffentliche Felder/Eigenschaften zu serialisieren.
Typische Serializer (JsonSerializer, XmlSerializer) arbeiten mit öffentlichen Members. Wenn eine Eigenschaft keinen öffentlichen Getter/Setter hat, kann der Wert nicht in JSON/XML landen, und du fragst dich, warum dort null steht.
Fehler Nr.3: Fehlender parameterloser Konstruktor.
Für XmlSerializer ist ein öffentlicher parameterloser Konstruktor Pflicht. Fehlt er, gibt es eine Exception bei der Deserialization.
Fehler Nr.4: Falsches Verständnis von Objekt-Referenzen.
Wenn ein Objekt eine Referenz auf ein anderes enthält, serialisiert man "by value" (als eingebettetes Objekt). Referenzen werden nicht erhalten, das kann zu Duplikaten oder Problemen mit zyklischen Referenzen führen.
Fehler Nr.5: Versuch, Formate zu mixen.
XML und JSON sind unterschiedliche Formate mit unterschiedlichen Serializer-Implementierungen. Du kannst keinen JSON-String dem XmlSerializer übergeben und umgekehrt — das führt zu Fehlern.
GO TO FULL VERSION