2016-11-09 5 views
-1

Say Ich habe einige JSON wie folgt aus:Json.Net Deserialize Dereferenziere

[{"$id": 1, Prop1: true, Prop2: {"$id": 2, Prop2: {"$id": 3, SomeProp: true}}}, {"$ref" : 3}] 

Und ich JsonConvert.DeserializeObject (aboveJson). Wie kann ich sicherstellen es diese deserialisiert in:

[{Prop1: true}, {SomeProp: true}] //[0] = id1, [1] = id3 

Statt dessen:

[{Prop1: true}, null] //[0] = id1, [1] = null because it doesn't match on "$ref" down the hierarchy. 

Edited für Klarheit: Wie kommt es, wenn ich diesen Code ausführen

public class StackOverflow 
    { 
     public bool Prop1 { get; set; } 
    } 
static void Main(string[] args) 
{ 
    string json = @"[{""$id"": ""1"", Prop1: true, Prop2: {""$id"": ""2"", Prop2: {""$id"": ""3"", Prop1: true}}}, {""$ref"" : ""3""}]"; 
    dynamic result = JsonConvert.DeserializeObject<List<StackOverflow>>(json); 

} 

result [0] ist eine StackOverflow-Klasse. Ergebnis [1] ist null. Wie bekomme ich es zur Dereferenzierung? Was vermisse ich?

+0

Suche Antwort hier: http://stackoverflow.com/questions/23505381/json-tree-modifications-that-dont-break-ref-references – MaitlandMarshall

+0

Haben Sie das JSON von Hand eingegeben? Weil Json.NET '$ ref" 'und' "$ id" 'Werte benötigt, um Strings zu sein, keine Ganzzahlen. – dbc

+0

Ja, tut mir leid, es ist nur Pseudo-Code. – MaitlandMarshall

Antwort

2

Die Eigenschaften "ref" und "$id" werden von Json.NET eingefügt, wenn Referenzverfolgung und -archivierung aktiviert ist. Informationen zur Dokumentation finden Sie unter Siehe Preserving Object References. Um das ursprüngliche Objektdiagramm zu deserialisieren, muss daher die Einstellung JsonSerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects verwendet werden.

Auch wenn diese Einstellung aktiviert ist, stimmt das vorgeschlagene Datenmodell nicht mit Ihrem JSON überein. Die formatierte JSON ist wie folgt:

[ 
    { 
    "$id": "1", 
    "Prop1": true, 
    "Prop2": { 
     "$id": "2", 
     "Prop2": { 
     "$id": "3", 
     "Prop1": true 
     } 
    } 
    }, 
    { 
    "$ref": "3" 
    } 
] 

Wie man sehen kann, ist der erste Eintrag in dem Array hat zwei Eigenschaften, von denen einer ein verschachteltes Objekt mit einem anderen inneren verschachteltes Objekt ist. Der zweite Eintrag im Array ist ein Verweis auf das innerste verschachtelte Objekt vom ersten Eintrag. Aufgrund der verschachtelten Referenz, können Sie nicht auf eine flache List<StackOverflow> wie folgt deserialisieren:

public class StackOverflow 
{ 
    public bool Prop1 { get; set; } 
} 

Stattdessen müssen Sie eine rekursive Modell wie folgt definieren:

public class StackOverflow 
{ 
    public bool? Prop1 { get; set; } 
    public StackOverflow Prop2 { get; set; } 
} 

Dann wird Ihr Deserialisierung Code aussehen würde, wie:

 string json = @"[{""$id"": ""1"", Prop1: true, Prop2: {""$id"": ""2"", Prop2: {""$id"": ""3"", Prop1: true}}}, {""$ref"" : ""3""}]"; 

     var settings = new JsonSerializerSettings 
     { 
      PreserveReferencesHandling = PreserveReferencesHandling.Objects, 
     }; 
     var result = JsonConvert.DeserializeObject<StackOverflow []>(json, settings); 

Beispiel fiddle.

Wenn wir nun wieder serialisiert ohne PreserveReferencesHandling.Objects wie folgt:

 var settingsOut = new JsonSerializerSettings 
     { 
      Formatting = Formatting.Indented, 
      NullValueHandling = NullValueHandling.Ignore, 
     }; 
     var jsonWithoutRef = JsonConvert.SerializeObject(root, settingsOut); 

     Console.WriteLine("Re-serialized with PreserveReferencesHandling.None"); 
     Console.WriteLine(jsonWithoutRef); 

Wir sehen, dass die innerste Instanz von StackOverflow korrekt an der zweiten Array Stelle platziert wird:

[ 
    { 
    "Prop1": true, 
    "Prop2": { 
     "Prop2": { 
     "Prop1": true 
     } 
    } 
    }, 
    { 
    "Prop1": true 
    } 
] 
Verwandte Themen