CodeGym /Kurse /C# SELF /Serialisierung konfigurieren (

Serialisierung konfigurieren ( JsonSerializerOptions)

C# SELF
Level 45 , Lektion 3
Verfügbar

1. Einführung

Alles gut, wenn deine Anforderungen dem Default-Verhalten entsprechen. Aber oft verlangt der Kunde (oder ein fremdes Backend) ein sehr spezifisches Format: überall camelCase, Datumsangaben im ISO 8601-Stil, null-Auslassungen, custom Converter und sonstige Freuden der Integration.

Hier kommt unser neuer Freund ins Spiel — die Klasse JsonSerializerOptions.

Wenn Serialisierung eine Küche wäre, ist diese Klasse deine Gewürzsammlung, Töpfe und geheimen Zutaten, mit denen du die Serialisierung nach deinem Geschmack würzen kannst.

Wie du JsonSerializerOptions benutzt

Um den Serialisierungs- oder Deserialisierungsprozess anzupassen, übergibst du einfach ein Options-Objekt an die Methoden des Serializers:

using System.Text.Json;

var options = new JsonSerializerOptions
{
    // Hier kommen deine Einstellungen
};

string json = JsonSerializer.Serialize(myObject, options);
var obj = JsonSerializer.Deserialize<MyType>(json, options);

Dieses Muster sieht man überall: du erstellst ein JsonSerializerOptions, passt es an (siehe unten) und gibst es an die Serializer-Methoden Serialize/Deserialize weiter.

Wichtig: Dasselbe JsonSerializerOptions-Objekt kann (und sollte) für mehrere Serialisierungen wiederverwendet werden.

2. Grundlegende Einstellungen von JsonSerializerOptions

Schauen wir uns die beliebtesten "Regler" und "Schalter" dieser Klasse an.

JSON-Formatierung — WriteIndented

Stören dich einzeilige JSON-Ketten? Kein Problem — aktiviere hübsche Einrückungen!

var options = new JsonSerializerOptions
{
    WriteIndented = true // Schönes, "menschliches" JSON
};

var person = new Person { Name = "Anna", Age = 30 };
string json = JsonSerializer.Serialize(person, options);

Console.WriteLine(json);

Ausgabe:

{
  "Name": "Anna",
  "Age": 30
}

Ohne WriteIndented = true hättest du das triste {"Name":"Anna","Age":30}. Im Production-Umfeld nutzt man meist minifizierten JSON (spart Platz), für Debugging und Logs nimmt man formatierten JSON.

Namenkonventionen — PropertyNamingPolicy

Oft verlangt ein API, dass Property-Namen im camelCase sind (z. B. firstName statt FirstName). In .NET sind Properties normalerweise PascalCase — hier hilft die Eigenschaft PropertyNamingPolicy:

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

var person = new Person { Name = "Oleg", Age = 25 };
string json = JsonSerializer.Serialize(person, options);
Console.WriteLine(json); // {"name":"Oleg","age":25}

Wenn du einen eigenen Stil brauchst (z. B. ALLE GROSSBUCHSTABEN), kannst du eine eigene Implementierung von JsonNamingPolicy schreiben. Meistens reicht CamelCase aber aus.

3. Eigenschaften ignorieren

null-Werte überspringen oder nicht — DefaultIgnoreCondition

Manchmal sollen Felder mit leeren (null) Werten gar nicht im JSON auftauchen. Gründe: kompakteres JSON oder ein externes System, das nicht gut mit null klarkommt.

Dafür nutzt du die Eigenschaft DefaultIgnoreCondition:

using System.Text.Json.Serialization;

var options = new JsonSerializerOptions
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

var person = new Person { Name = null, Age = 22 };
string json = JsonSerializer.Serialize(person, options);
Console.WriteLine(json); // {"Age":22}

Wenn du nicht nur null, sondern auch Default-Werte ignorieren willst (z. B. int=0), verwende WhenWritingDefault:

options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault;

Felder einbeziehen — IncludeFields und [JsonInclude]

Standardmäßig werden nur öffentliche Properties mit offenem Setter serialisiert. Wenn du auch Felder (fields) serialisieren möchtest, kannst du das einschalten:

var options = new JsonSerializerOptions
{
    IncludeFields = true
};

Beispielklasse:

public class Item
{
    public string Name;
    public int Id { get; set; }
}

var item = new Item { Name = "Book", Id = 12 };
string json = JsonSerializer.Serialize(item, options);
// {"Name":"Book","Id":12}

Für die Serialisierung privater Felder/Properties kannst du das Attribut [JsonInclude] verwenden, aber das ist Thema einer anderen Vorlesung.

4. Wertkonvertierung

Datumsformatierung — Converters

Standardmäßig serialisiert System.Text.Json Daten strikt im ISO 8601-Format (z. B. "2023-12-27T15:30:45.123Z"), was meist praktisch ist. Es gibt aber Fälle, in denen ein spezielles Datums-/Zeitformat gefordert ist.

Dafür hängst du eigene Converter an. Ein simples Beispiel:

using System.Text.Json;
using System.Text.Json.Serialization;

public class CustomDateTimeConverter : JsonConverter<DateTime>
{
    private string _format = "yyyyMMdd";

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var date = reader.GetString();
        return DateTime.ParseExact(date, _format, null);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(_format));
    }
}

// Converter benutzen
var options = new JsonSerializerOptions();
options.Converters.Add(new CustomDateTimeConverter());

var dateObj = new { Date = new DateTime(2022, 1, 5) };
string json = JsonSerializer.Serialize(dateObj, options); // {"Date":"20220105"}

5. Nützliche Hinweise

Groß-/Kleinschreibung bei der Deserialisierung ignorieren — PropertyNameCaseInsensitive

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};

var json = "{\"name\":\"Vasya\",\"age\":33}";
var person = JsonSerializer.Deserialize<Person>(json, options);
// person.Name == "Vasya"

Verschachtelung und maximale Objekt-Tiefe steuern — MaxDepth

var options = new JsonSerializerOptions
{
    MaxDepth = 32 // Standard ist 64
};

Wenn deine Objekte extrem tief verschachtelt sein können — zum Beispiel ein Baum mit Verweisen auf Eltern und Kinder — dann ist es besser, das Modell anders zu gestalten.

Kommentare in JSON — ReadCommentHandling (Deserialisierung)

JSON unterstützt offiziell keine Kommentare, aber manchmal trifft man auf "kreative" Dateien mit //-Kommentaren.

var options = new JsonSerializerOptions
{
    ReadCommentHandling = JsonCommentHandling.Skip
};

string json = "{\n  \"Name\": \"Ivan\", // Benutzername\n  \"Age\": 30\n}";
var person = JsonSerializer.Deserialize<Person>(json, options);

Sonderzeichen-Unterstützung — Encoder

Manchmal möchtest du kontrollieren, wie der Serializer Zeichen escaped (z. B. damit Kyrillisch nicht in \uXXXX umgewandelt wird). Du kannst einen eigenen Encoder angeben:

using System.Text.Encodings.Web;

var options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

Vorsicht: Nutze das mit Bedacht, sonst könnten Emojis oder Schriftzeichen plötzlich in Unicode-Sequenzen "verschwinden"!

6. Typische Fehler bei der Konfiguration der Serialisierung

Fehler Nr.1: Den öffentlichen Setter vergessen. Feld oder Property wird nicht serialisiert, weil kein öffentlicher Setter vorhanden ist oder es privat ist.

Fehler Nr.2: Falsches Ignorieren von null-Werten. Bei aktivierter DefaultIgnoreCondition landen Properties mit null nicht im JSON, obwohl du das vielleicht nicht erwartet hast.

Fehler Nr.3: Falsches Datumsformat. Das Datum wird nicht im gewünschten Format serialisiert — hänge einen custom Converter (JsonConverter) an.

Fehler Nr.4: Erwartung einer festen Reihenfolge der Properties. Der JSON-Standard garantiert keine Feldreihenfolge. Wenn ein API eine strikte Reihenfolge verlangt, musst du entweder das Modell ändern oder auf Drittanbieter-Bibliotheken ausweichen.

Fehler Nr.5: Unterschiedliche Einstellungen beim Serialisieren und Deserialisieren. Wenn du nicht dieselben JsonSerializerOptions für Schreiben und Lesen verwendest, kann es zu Problemen kommen — z. B. mit Namens-Casing oder Formaten.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION