Json.Net Serialisierung von Typ mit polymorphem Child-Objekt

8

Wir möchten in der Lage sein, json von / nach C # -Klassen zu serialisieren / deserialisieren, wobei die Hauptklasse eine Instanz eines polymorphen untergeordneten Objekts hat. Dies ist mit der Einstellung TypeNameHandling.Auto von Json.Net einfach. Dies möchten wir jedoch ohne das Feld "$ type" tun.

Der erste Gedanke ist, dass wir "$ type" in einen Wert unserer Wahl umbenennen können und dass der Wert für den Typ eine Aufzählung ist, die die Untertypen richtig abbildet. Ich habe das nicht als Option gesehen, würde mich aber freuen zu hören, ob es möglich ist.

Der zweite Gedanke war in den folgenden Zeilen ... Unten ist ein erster Durchgang bei Klassen, wobei die oberste Klasse einen Indikator (SubTypeType) hat, welcher Datentyp in dem Kindobjekt (SubTypeData) enthalten ist. Ich habe ein wenig in die Json.Net-Dokumentation gegraben und habe ein paar Dinge ausprobiert, hatte aber kein Glück.

Wir haben derzeit volle Kontrolle über die Datendefinition, aber sobald sie implementiert ist, sind die Dinge abgeschlossen.

%Vor%     
GaTechThomas 09.04.2015, 02:20
quelle

3 Antworten

7

Die Informationen zum Subtyp in der Containerklasse sind aus zwei Gründen problematisch:

  1. Auf die Containerklasseninstanz kann nicht zugegriffen werden, wenn Json.NET die enthaltene Klasse liest.
  2. Wenn Sie die Eigenschaft SubTypeClassBase später in eine Liste umwandeln müssen, können Sie die Informationen zum Untertyp nicht hinzufügen.

Ich würde stattdessen empfehlen, die Subtypinformationen als eine Eigenschaft in der Basisklasse hinzuzufügen:

%Vor%

Nun wird der benutzerdefinierte Subtyp enum serialisiert, wenn ein Objekt, das SubTypeClassBase zuweist, serialisiert wird. Danach können Sie für die Deserialisierung ein JsonConverter erstellen, das den JSON für ein bestimmtes Objekt lädt SubTypeClassBase in ein temporäres JObject , überprüft den Wert der Eigenschaft "Type" , und deserialisiert das JSON-Objekt als die geeignete Klasse.

Prototyp-Implementierung unten:

%Vor%     
dbc 09.04.2015, 06:32
quelle
1

Sie können es mit der JsonSubtypes -Konvertierer-Implementierung versuchen, die die Registrierung des Typ-Mappings mit Enum-Werten unterstützt .

In Ihrem Fall sieht das so aus:

%Vor%     
manuc66 20.06.2017 18:32
quelle
1

Hier ist ein vollständiges Beispiel, das sowohl als auch JSON mit polymorphen Objekten lesen kann.

Angenommen, wir haben die folgende Klassenstruktur:

%Vor%

Wir können einen benutzerdefinierten Konverter verwenden, der beim Serialisieren ein zusätzliches Feld in JSON namens type erstellt und beim Deserialisieren liest.

%Vor%

Sie können diesen Konverter in einer Container-Klasse wie folgt verwenden:

%Vor%

Alternativ können Sie JSON.net's eingebauten Typhinweis verwenden, statt Ihren eigenen JsonConverter zu rollen, aber es ist nicht so flexibel und erstellt sehr untragbaren JSON.

%Vor%     
blade 27.03.2018 16:15
quelle

Tags und Links