So entstehen C#-Klassen aus einem JSON-Beispiel

Füge ein JSON-Beispiel ein — eine API-Antwort, eine Konfigurationsdatei oder einen Webhook-Body — und die Seite schreibt die passenden C#-Klassen: eine Klasse pro Objektform, mit öffentlichen Eigenschaften und { get; set; }-Accessoren, alles in einer Datei, die du kopieren kannst. Die Umwandlung läuft im Browser, die Nutzlast wird nie hochgeladen, und die Seite arbeitet nach dem Laden offline weiter.

Jeder Eigenschaftsname ist ein gültiger C#-Bezeichner: ein Schlüssel, der mit einem Schlüsselwort kollidiert, wird als verbatim-Bezeichner geschrieben (@class), und ein Schlüssel mit Zeichen, die C# ablehnt, wird neu aufgebaut, während der Originalschlüssel in einem [JsonPropertyName]-Attribut erhalten bleibt, damit System.Text.Json die Nutzlast weiter zuordnet. Typen, Klassennamen und Verschachtelung stammen aus dem eingefügten Beispiel, deshalb ist das Ergebnis ein Entwurf zum Prüfen und kein fertiges Modell.

  1. Füge das JSON oben ein oder tippe es ein. Kommentare sind erlaubt: eine // oder /* */-Zeile, die allein über einer Eigenschaft steht, wird zu einer /// <summary>-Zeile in der erzeugten Klasse.
  2. Klicke auf C#-Klassen erzeugen. Die Datei erscheint darunter, mit der C#-Grammatik eingefärbt, und die Meldung darüber bestätigt den Lauf oder nennt die Zeile, an der er abgebrochen ist.
  3. Klicke auf C#-Klassen kopieren, um den Code ohne Farben in die Zwischenablage zu legen, und füge ihn in eine .cs-Datei deines Projekts ein.
  4. Ändere das JSON und erzeuge erneut, wenn ein Wert nicht passt: das vorherige Ergebnis wird bei jedem Lauf verworfen, auch bei Fehlern, sodass das Kopierte immer zur aktuellen Eingabe gehört.

Wie Werte, Schlüssel und Arrays zu C# werden

Welchen C#-Typ jeder JSON-Wert erhält

Zahlen werden nach Bereich typisiert: eine ganze Zahl, die in Int32 passt, wird int, eine größere ganze Zahl wird long bis 2^53, und alles mit Nachkommastellen oder darüber hinaus wird double, sodass 2147483648 und 1e10 nicht mehr in einem int landen. true und false werden bool, und ein Wert, der im ganzen Beispiel null ist, wird string. Ein String bleibt string, außer er ist wie ein Datum geformt und lässt sich als solches lesen: 2024-05-06, 2024/05/06 10:00, 12/31/2024 und May 6, 2024 werden DateTime, während 20240506, 1-2, R2D2 und numerische IDs ihren genauen Text behalten.

Trägt ein Feld in verschiedenen Elementen eines Arrays unterschiedliche Werttypen, gewinnt der weitere Zahlentyp (int mit long ergibt long, int mit 2.5 ergibt double), und jede andere Abweichung wird object. Ein Feld, das in einem Element null und in einem anderen typisiert ist, übernimmt den Typ des nicht-null-Elements, ein einzelnes null löscht also nicht, was die übrigen Zeilen zeigen.

Wie aus einem JSON-Schlüssel eine C#-Eigenschaft wird

Die Eigenschaft behält den JSON-Schlüssel, wo C# es zulässt. Ein reserviertes Wort wird als verbatim-Bezeichner geschrieben, aus class wird also @class, das kompiliert und weiterhin den gleichnamigen Schlüssel zuordnet. Ein Schlüssel mit Zeichen, die C# ablehnt, wird neu aufgebaut: user-name wird zu userName, first name zu firstName, 1st zu _1st, a.b zu aB und ein leerer Schlüssel zu value. Zwei Schlüssel, die auf denselben Bezeichner fallen, bekommen ein numerisches Suffix statt sich zu überschreiben, aus a.b und a&b werden also aB und aB2.

Weicht ein Eigenschaftsname vom JSON-Schlüssel ab, trägt die Eigenschaft [JsonPropertyName("...")] und die Datei erhält ein using System.Text.Json.Serialization; das Attribut entfällt, wenn es nur den Eigenschaftsnamen wiederholen würde, und ein reservierter Schlüssel wie class braucht keines, weil der verbatim-Name bereits passt. Dieses Attribut ist die einzige Konfiguration in der Datei: keine Serializer-Optionen, kein Schema, keine Annotation für unveränderte Schlüssel.

Objekte, Arrays und verschachtelte Klassen

Jede unterschiedliche Objektform wird eine Klasse, benannt nach ihrem JSON-Schlüssel in PascalCase und nie doppelt in der Datei: ein zweites data wird Data2, ein verschachteltes data in wrap wird WrapData, zwei Zweige können also nicht mehr beide Data beanspruchen. Eine Klasse heißt außerdem nie wie die Typen, die die Datei selbst nutzt (List, String, Object, DateTime), weil dieser Name sie verdecken würde, und kein Member darf den Namen seiner eigenen Klasse wiederholen.

Arrays werden als Ganzes gelesen, nicht nur über das erste Element: [1, 2, 3] wird List<int>, [1, 2.5] wird List<double>, ein Array aus Objekten wird eine Liste einer zusammengeführten Klasse mit allen Schlüsseln, die in irgendeinem Element vorkommen, und ein Array, das Objekte mit Skalaren mischt, wird List<object>. Ein leeres Array wird als Platzhalter List<string>. Das Wurzelobjekt heißt immer Root; ein Array an der Wurzel wird in einem Kommentar vermerkt und aus den zusammengeführten Elementen modelliert, und eine skalare Wurzel ergibt eine leere Klasse mit dem Hinweis, dass keine Eigenschaften abgeleitet werden konnten.

Was die erzeugte Datei ist und was nicht

Die Ausgabe ist eine einzelne C#-Quelldatei: ein Generierungskommentar mit Zeitstempel, die using-Direktiven, die die Datei wirklich braucht, und danach die Klassen. Es ist reines C# mit { get; set; }-Eigenschaften, ohne Konstruktor und ohne Namespace, passt also in jedes Projekt ab .NET Core 3.0; kompiliert wird hier nichts, die Seite schreibt nur den Text.

Die Typen stammen aus dem einen Beispiel, das du einfügst: ein Feld, das im Beispiel immer 0 ist, wird int, auch wenn die Produktion eine Dezimalzahl sendet, und ein Array, das zufällig leer ist, wird List<string>. Behandle das Ergebnis als Entwurf: prüfe die Typen, auf die du dich verlässt, benenne die Wurzelklasse um, wie du willst, und behalte die JSON-Kommentare im Beispiel, denn nur sie werden zu Dokumentation.

Zuletzt verwendet: