1. Einführung
Wenn du gerade erst mit Serialisierung in .NET anfängst, ist es ganz natürlich zu fragen: wozu noch eine Bibliothek, wenn es schon das eingebaute System.Text.Json gibt? Die Antwort ist einfach: Newtonsoft.Json kam früher und hat sich über Jahre hinweg zu einem der flexibelsten Tools für JSON in .NET entwickelt.
Es wurde de-facto zum Standard, weil es komplexe Szenarien unterstützt: benutzerdefinierte Contracts, mächtige Converter, Serialisierung privater Felder, LINQ für JSON, dynamische Objekte (JObject), flexible Handhabung von zyklischen Referenzen und viele Datums-/Zeitformate. Viele Bibliotheken und APIs nutzen Json.NET immer noch „unter der Haube“.
Wichtig: in manchen Szenarien ist das eingebaute System.Text.Json noch nicht so mächtig wie Newtonsoft.Json, deshalb lohnt sich das Lernen von Json.NET weiterhin.
Wie man Newtonsoft.Json (Json.NET) einbindet
Installiere das Paket via NuGet:
dotnet add package Newtonsoft.Json
Binde den Namespace ein:
using Newtonsoft.Json;
2. Serialisierung mit Newtonsoft.Json
Nehmen wir die klassische Klasse Person:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Ein Objekt in einen JSON-String serialisieren
Person person = new Person { Name = "Ivan", Age = 30 };
// Serialisierung zu JSON
string json = JsonConvert.SerializeObject(person);
Console.WriteLine(json);
// Ausgabe: {"Name":"Ivan","Age":30}
JSON zurück in ein Objekt deserialisieren
string json = "{\"Name\":\"Ivan\",\"Age\":30}";
Person person = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine($"{person.Name}, {person.Age}");
// Ausgabe: Ivan, 30
Was passiert „unter der Haube“?
Newtonsoft.Json geht alle öffentlichen Eigenschaften (public) durch, serialisiert sie in JSON und schreibt das in einen String. Beim Deserialisieren matcht es die Keys aus dem JSON mit den Eigenschaftsnamen und füllt das Objekt.
3. Serialisierung von Collections
Collections und Arrays serialisieren
Bei Collections funktioniert alles „out of the box“.
List<Person> people = new List<Person>
{
new Person { Name = "Ivan", Age = 30 },
new Person { Name = "Maria", Age = 25 }
};
string json = JsonConvert.SerializeObject(people);
// Ausgabe: [{"Name":"Ivan","Age":30},{"Name":"Maria","Age":25}]
List<Person> deserialized = JsonConvert.DeserializeObject<List<Person>>(json);
// Jetzt hast du wieder eine List<Person>!
Besonderheiten bei Dictionaries
var dict = new Dictionary<string, int>
{
["apple"] = 2,
["banana"] = 5
};
string json = JsonConvert.SerializeObject(dict);
// Ausgabe: {"apple":2,"banana":5}
var deserializedDict = JsonConvert.DeserializeObject<Dictionary<string,int>>(json);
// Alles funktioniert!
Wenn die Keys keine Strings sind (z.B. Dictionary<int,string>), wandelt Json.NET die Keys beim Serialisieren in Strings um und versucht beim Deserialisieren zurück zu konvertieren. Bei komplexen Keys (z.B. Guid) ist es zuverlässiger, Dictionary<string, TValue> zu verwenden.
4. Arbeiten mit verschachtelten Objekten und Hierarchien
public class Order
{
public int Id { get; set; }
public Person Customer { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public string Title { get; set; }
public double Price { get; set; }
}
Order order = new Order
{
Id = 123,
Customer = new Person { Name = "Ivan", Age = 30 },
Products = new List<Product>
{
new Product { Title = "Laptop", Price = 50000.0 },
new Product { Title = "Maus", Price = 1500.0 }
}
};
string json = JsonConvert.SerializeObject(order);
Console.WriteLine(json);
Ergebnis: verschachtelte Objekte werden korrekt in der JSON-Struktur abgebildet.
5. Serialisierung per Attribute konfigurieren
Eigenschaft ignorieren
public class Person
{
public string Name { get; set; }
[JsonIgnore]
public int Age { get; set; }
}
Jetzt wird Age nicht ins JSON gelangen.
Eigenschaft umbenennen
public class Person
{
[JsonProperty("full_name")]
public string Name { get; set; }
}
Im JSON wird der Name als "full_name" erscheinen.
6. Flexible Konfiguration: JsonSerializerSettings
Formatierung (schön formatiertes mehrzeiliges JSON):
string json = JsonConvert.SerializeObject(
people,
Formatting.Indented
);
Ergebnis:
[
{
"Name": "Ivan",
"Age": 30
},
{
"Name": "Maria",
"Age": 25
}
]
Häufig verwendete Einstellungen:
| Eigenschaft | Beschreibung |
|---|---|
|
Wie mit null-Eigenschaften verfahren werden soll (überspringen oder explizit null schreiben) |
|
Sollen Default-Werte übersprungen werden? |
|
Wie mit Referenzzyklen umgehen |
|
Format-String für Datum und Zeit |
Beispiel, das null überspringt:
string json = JsonConvert.SerializeObject(
person,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }
);
7. Arbeiten mit dynamischen JSON-Strukturen: JObject, JArray u.ä.
Wenn die JSON-Struktur vorher unbekannt ist, nutze die Typen aus Newtonsoft.Json.Linq:
using Newtonsoft.Json.Linq;
string json = @"{
'Name': 'Ivan',
'Age': 30,
'Skills': ['C#', 'SQL', 'JSON']
}";
JObject obj = JObject.Parse(json);
Console.WriteLine(obj["Name"]); // Ivan
Console.WriteLine(obj["Skills"][0]); // C#
JSON „on the fly“ erstellen:
var jObj = new JObject
{
["Status"] = "Success",
["Result"] = new JArray("item1", "item2", "item3")
};
Console.WriteLine(jObj.ToString(Formatting.Indented));
JObject und JArray sind Repräsentationen eines JSON-Objekts bzw. -Arrays, im Grunde praktische Collections.
8. Nützliche Tipps
Zyklische Referenzen
Newtonsoft.Json kann diese flexibel behandeln:
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string json = JsonConvert.SerializeObject(obj, settings);
So werden Zyklen übersprungen. Um Referenzen zu erhalten, kannst du ReferenceLoopHandling.Serialize zusammen mit [JsonObject(IsReference = true)] verwenden.
Serialisierung von anonymen und dynamischen Objekten
var anon = new { Foo = 42, Bar = "Hello" };
string json = JsonConvert.SerializeObject(anon);
// {"Foo":42,"Bar":"Hello"}
Validierung und Fehlerbehandlung
try
{
Person p = JsonConvert.DeserializeObject<Person>(brokenJson);
}
catch (JsonSerializationException ex)
{
Console.WriteLine("Fehler beim Deserialisieren: " + ex.Message);
}
Vergleich Newtonsoft.Json vs System.Text.Json
| Newtonsoft.Json (Json.NET) | System.Text.Json (.NET) | |
|---|---|---|
| .NET-Unterstützung | .NET Framework/Standard/6+ | .NET Core 3.0+ / .NET 5/6/9 |
| LINQ zu JSON (JObject/JArray) | Ja | Nein |
| Flexible Konfiguration | Sehr umfangreich | Eingeschränkt |
| Attribute ([JsonProperty], ...) | Ja | Ja (teilweise, weniger Möglichkeiten) |
| Unterstützung privater Eigenschaften | Ja | Nein |
| Geschwindigkeit | Langsamer in einigen Szenarien | Schneller |
| Komplexe Converter | Ja | Ja (weniger flexibel, noch) |
| Unterstützung für DataTable, DataSet | Ja | Nein |
| Dokumentation und Beispiele | Sehr viele | Wächst |
9. Anfängerfehler und typische Fallstricke
Fehler #1: Eigenschaften werden nach der Deserialisierung null.
Oft hat die Eigenschaft keinen Setter oder ein parameterloser Konstruktor fehlt — dem Serializer fehlt etwas, womit er das Objekt füllen kann.
Fehler #2: Namen der Eigenschaften stimmen zwischen JSON und Klasse nicht überein.
Wenn im JSON das Feld "fullName" heißt, die Klasse aber FullName, nutze [JsonProperty] oder konfiguriere einen ContractResolver zum Mapping der Namen.
Fehler #3: Serialisierung funktioniert standardmäßig nur mit öffentlichen Eigenschaften.
Private Felder/Eigenschaften werden ohne zusätzliche Einstellungen nicht serialisiert. Du brauchst Converter oder spezielle Resolver/Contracts.
Fehler #4: Zyklische Referenzen führen zu StackOverflowException.
Gegenseitige Referenzen zwischen Objekten können die Serialisierung ohne passende Einstellungen endlos machen. Konfiguriere die Referenzbehandlung (z.B. ReferenceLoopHandling) oder passe das Datenmodell an.
GO TO FULL VERSION