100 % lokal — Ihre Daten verlassen nie Ihren Browser

JSON in C# — Records, die System.Text.Json liest

Ein JSON-Beispiel in C#-Records oder Klassen verwandeln. Jede umbenannte Property trägt ein JsonPropertyName-Attribut, der Deserializer findet ihn.

Sofort Privat Null Cookies
Stil

JSON-Eingabe

C#-Ausgabe

Was dieses Werkzeug tut

Aus einer JSON-Probe werden C#-Records, einer je Objekt.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
using System.Text.Json.Serialization;

public record Root(
    [property: JsonPropertyName("id")] long Id,
    [property: JsonPropertyName("firstName")] string FirstName,
    [property: JsonPropertyName("address")] Address Address
);

public record Address(
    [property: JsonPropertyName("city")] string City
);

Positionale Records brauchen C# 9; das using erscheint nur, wenn ein Attribut erscheint.

Das Ziel des Attributs zählt

C#-Eigenschaftsnamen stehen in PascalCase: firstName wird FirstName, content-type wird ContentType. System.Text.Json vergleicht nur auf Wunsch ohne Rücksicht auf Groß- und Kleinschreibung und nie über einen Bindestrich hinweg — also wird der Schlüssel per Attribut festgehalten.

Das Präfix property: ist der Teil, den man leicht falsch macht. Bei einem positionalen Record ist der Parameter nicht die Eigenschaft: ein Attribut ohne Ziel bleibt am Konstruktorparameter, und der Serialisierer sieht es nie. Mit Ziel landet es dort, wo es gelesen wird.

Die Typen

  • Ganzzahlen werden long, Dezimalzahlen double — beide breiter als die 32-Bit-Vorgabe, denn eine JSON-Zahl verspricht nicht, hineinzupassen.
  • null und unbekannte Werte werden object?, was eingeschaltete nullable Referenztypen voraussetzt (Vorgabe seit .NET 6).
  • Arrays werden List<T>; ein gemischtes Array wird List<object>, außer es mischt Ganzzahlen und Dezimalzahlen — dann deckt List<double> beide ab.
  • Ein Skalar an der Wurzel wird abgelehnt: C# hat keinen globalen Typalias, 42 hat also nichts, was es werden könnte. Ein Array von Objekten gibt Ihnen den Record seines Elements, den Sie an eine List<Root> binden.

Was eine Probe nicht sagen kann

Keine Eigenschaft ist über jene object? hinaus nullbar, und keine hat einen Vorgabewert: das Dokument hatte für jede einen Wert. required und init lohnen sich, sobald Sie wissen, welche Schlüssel wirklich Pflicht sind — eine Probe sagt nur, welche zufällig da waren.

Datenschutz ab Werk

Alles läuft lokal in deinem Browser mit JavaScript. Deine Daten werden nie hochgeladen, wodurch das Tool auch für sensible Inhalte sicher ist und offline funktioniert.

Häufige Fragen

Warum `[property: JsonPropertyName(...)]` und nicht nur `[JsonPropertyName(...)]`?
Weil ein positionaler Record-Parameter noch keine Eigenschaft ist. Ohne das Ziel `property:` landet das Attribut auf dem Konstruktorparameter, wohin der Serialisierer nie schaut — der Compiler warnt sogar. Das Ziel verschiebt es auf die erzeugte Eigenschaft, wo `System.Text.Json` es liest.
Ich nutze Newtonsoft.Json. Was ändere ich?
Das Attribut und sein using: `[property: JsonProperty("content-type")]` mit `Newtonsoft.Json`. Sonst unterscheidet sich nichts — Eigenschaftsnamen, Typen und Record-Form sind gleich. Newtonsoft vergleicht zudem standardmäßig ohne Rücksicht auf Groß- und Kleinschreibung, `camelCase`-Schlüssel gehen also oft ganz ohne Attribut.
Record oder Klasse?
Der Record ist die Vorgabe: Wertgleichheit, `with`-Ausdrücke und ein Konstruktor, der jedes Feld beim Erzeugen ausdrücklich macht. Die Klassen-Option gibt stattdessen setzbare Eigenschaften — was eine ältere Codebasis oder ein Framework erwartet, das Objekte per Zuweisung baut. Die abgeleiteten Typen sind identisch.

Ähnliche Konverter