2016-03-11 122 views
0

我有一個以名爲ProductParts的對象爲中心的C#應用​​程序,一個部分可以包含一個或多個子ProductParts。但是,零件也可以以間接方式包含對其他零件的引用。JSON.net反序列化對null的引用

class ProductPart 
{ 
    List<ProductPart> ProductParts; 
    ProductPart MaterialReference { get; set; } 
    ProductPart ColorReference { get; set; } 
    ProductPart ActiveStateReference { get; set; } 
} 

我使用JSON.net來保存/加載這些零件。但是,我注意到某些參考文獻存在問題。

下面是一個瘦身的JSON文件示例來演示我的問題。

{ 
    "$id": "3", 
    "Name": "ProductName", 
    "ProductParts": { 
    "$id": "5", 
    "$values": [ 
     { 
     "$id": "6", 
     "Name": "top", 
     "ProductParts": { 
      "$id": "8", 
      "Name": "bottom", 
      "$values": [ 
      { 
       "$id": "9", 
       "MaterialReference": { 
       "$ref": "6" 
       }, 
       "ColorReference": { 
       "$ref": "6" 
       }, 
       "ActiveStateReference": { 
       "$ref": "6" 
       } 
      } 
      ] 
     } 
     } 
    ] 
    } 
} 

當我將這樣的文件加載到我的應用程序中時,參考字段爲空。這是因爲我在這裏創建了一個參考循環嗎?我試圖讓使用

ReferenceLoopHandling = ReferenceLoopHandling.Error

但出乎我的意料,這並不會引發錯誤JSON.net拋出一個錯誤在這種情況下。我創建了一個無法解析的數據結構嗎?

+0

我有類似的問題,我解決它的唯一方法是通過刪除循環引用。在我的例子中,我有一個'Report'對象,它有一個'ReportRow'對象的集合。每個「ReportRow」對象都引用了它所關聯的「Report」對象。從ReportRow中刪除'Report'引用修復了它。 –

+0

不,這不是因爲參考循環。如果您在序列化時看起來像是在使用'PreserveReferencesHandling = PreserveReferencesHandling.All'設置,那麼當您反序列化時,Json.Net應該很好地處理引用循環。事實上,在對你的JSON做了一些小調整之後,我能夠反序列化它。調整是「底部」名稱應該在ID 9以下,而不是8. 8是ProductParts數組的ID,它不能有名稱。我假設這是一個複製粘貼錯誤。這裏是小提琴:https://dotnetfiddle.net/Vh0KbM –

回答

0

您需要刪除班級中的循環引用。創建這樣一個映射類結構反序列化JSON的

class ProductPart 
    { 
     [JsonProperty("$id")] 
     public int Id { get; set; } 
     public string Name { get; set; } 
     [JsonProperty("ProductParts")] 
     List<ProductPartsA> ProductPartsA; 
    } 

    class ProductPartsA 
    { 
     [JsonProperty("$id")] 
     public int Id { get; set; } 
     public string Name { get; set; } 
     [JsonProperty("ProductParts")] 
     List<ProductPartsB> ProductPartsB; 
    } 

    class ProductPartsB 
    { 
     [JsonProperty("$id")] 
     public int Id { get; set; } 
     public string Name { get; set; } 
     [JsonProperty("$values")] 
     List<Values> Values; 
    } 

    class Values 
    { 
     [JsonProperty("$id")] 
     public int Id { get; set; } 
     public Reference MaterialReference { get; set; } 
     public Reference ColorReference { get; set; } 
     public Reference ActiveStateReference { get; set; } 
    } 

    class Reference 
    { 
     [JsonProperty("$ref")] 
     public string Ref { get; set; } 
    } 

顯然,這可以處理好繼承更好一點,但你的想法。然後,您可以通過簡單地反序列化您的json:

var myClass = JsonConvert.DeserializeObject<ProductPart>(jsonstr);