2016-11-09 188 views
-1

說,我有一些JSON這樣的:Json.Net反序列化提領

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

而且我用JsonConvert.DeserializeObject(aboveJson)。我如何才能確保其反序列化到這一點:

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

取而代之的是:

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

編輯的清晰度: 爲什麼當我運行這段代碼

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); 

} 

結果[0]是一個StackOverflow類。結果[1]爲空。我如何得到它的解除引用?我錯過了什麼?

+0

找到答案這裏: http://stackoverflow.com/questions/23505381/json-tree-modifications-that-dont-break-ref-references – MaitlandMarshall

+0

你手型的JSON?因爲Json.NET需要'「$ ref」'和'「$ id」'值爲字符串,而不是整數。 – dbc

+0

對不起,這只是僞代碼。 – MaitlandMarshall

回答

2

當啓用引用跟蹤和保存時,"ref""$id"屬性由Json.NET插入。有關文檔,請參閱請參閱Preserving Object References。因此,要反序列化原始對象圖,必須使用JsonSerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects的設置。

但是,即使啓用此設置,您提出的數據模型也與您的JSON不匹配。格式化的JSON如下:

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

正如可以看到,在陣列中的第一個條目具有兩個屬性,其中之一是與另一內部嵌套對象嵌套對象。數組中的第二個條目是對第一個條目中最內層嵌套對象的引用。因爲嵌套參考的,你不能反序列化到扁平List<StackOverflow>類似如下:

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

相反,你需要定義如下所示的遞歸模型:

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

那麼你的反序列化的代碼將如:

 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); 

樣本fiddle。現在

,如果我們重新序列PreserveReferencesHandling.Objects如下:

 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); 

我們看到的StackOverflow最裏面的實例被正確地放置在第二陣列的位置:

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