Wie kann die Sammlung mit verschiedenen Typen deserialisiert werden?

8

Ich habe einen JSON-Feed, der so aussieht (ich habe einige Felder entfernt, die für dieses Beispiel nicht notwendig sind):

%Vor%

In diesem Feed gibt es zwei Arten von Transaktionen: interne Transaktionen mit einem recipient und externe Transaktionen mit einem hsh und recipient_address .

Ich habe die folgenden Klassen für diese Struktur erstellt:

Wir haben also eine Basisklasse für alle ausgelagerten Ergebnisse ( PagedResult ) mit einer spezifischen Implementierung für Transaktionen ( TransactionPagedResult ). Dieses Ergebnis enthält eine Auflistung mit 0 .. * Transaktionen (abstrakte Klasse Transaction ). Sie sind zwar nicht vom Typ Transaction , aber vom Typ InternalTransaction oder ExternalTransaction , die Implementierungen von Transaction sind.

Meine Frage ist, wie ich JSON.NET damit umgehen kann. Ich möchte JSON.NET zu sehen, ob die aktuelle Transaktion es Parsing ist ein InternalTransaction oder ExternalTransaction ist, und fügen Sie in das Verzeichnis IEnumerable<Transaction> Sammlung in TransactionPagedResult der gemäß Art.

Ich habe meinen eigenen JsonConverter erstellt, den ich als Eigenschaft dem IEnumerable<Transaction> mit dem Attribut [JsonConverter(typeof(TransactionCreationConverter))] hinzugefügt habe, aber das hat nicht funktioniert, ich erhalte den folgenden Fehler:

  

Zusätzliche Information: Fehler beim Lesen von JObject von JsonReader. Strom   JsonReader Element ist kein Objekt: StartArray. Pfad "Transaktionen",   Linie 1, Position 218.

Ich verstehe, dass JSON.NET versucht, die gesamte Sammlung zu deserialisieren, aber ich möchte, dass jedes Objekt in der Sammlung einzeln deserialisiert wird.

Jeder?

    
Leon Cullens 15.06.2014, 12:47
quelle

1 Antwort

6

Ihre Frage ist im Wesentlichen ein Duplikat von diesem , und die Lösung ist die gleiche. Sie benötigen ein JsonConverter , um das korrekte Objekt zu instanziieren. Es gibt jedoch ein paar Unterschiede, die ich sehe.

Wenn Sie sich die Konverter-Implementierung von der anderen Antwort ansehen, können Sie sehen, dass sie nach einem booleschen Flag sucht JSON, um den zu instanziierenden Typ zu bestimmen. In Ihrem Fall gibt es kein solches Flag. Sie müssten also das Vorhandensein oder Nichtvorhandensein eines Feldes verwenden, um diese Bestimmung zu treffen. Außerdem ist Ihre Liste von Transaktionen im JSON eigentlich eine Liste von Objekten, die Transaktionen enthalten , also muss der Konverter dies auch berücksichtigen.

Mit diesen Änderungen sollte Ihr Konverter etwa so aussehen:

%Vor%

unter der Annahme, dass Ihre Klassen wie folgt definiert sind:

%Vor%

Um den letzten Teil Ihrer Frage zu beantworten, wenn Sie Ihre Liste mit einem [JsonConverter] -Attribut versehen, wird erwartet, dass der Konverter die gesamte Liste behandelt. Um die einzelnen Elemente zu bearbeiten, müssen Sie stattdessen [JsonProperty(ItemConverterType=typeof(TransactionConverter))] in der Liste verwenden. Ich habe die Klassendefinitionen oben bearbeitet, um dies deutlich zu machen.

    
Brian Rogers 15.06.2014, 16:36
quelle