2011-06-08 73 views
3

我有指向同一類型的另一個對象Parent屬性這個對象:反序列化不起作用

[JsonObject(IsReference = true)] 
class Group 
{ 
    public string Name { get; set; } 

    public Group(string name) 
    { 
     Name = name; 
     Children = new List<Group>(); 
    } 

    public IList<Group> Children { get; set; } 

    public Group Parent { get; set; } 

    public void AddChild(Group child) 
    { 
     child.Parent = this; 
     Children.Add(child); 
    } 
} 

序列化工作正常,並導致JSON看起來像這樣:

{ 
    "$id": "1", 
    "Name": "Parent", 
    "Children": [ 
    { 
     "$id": "2", 
     "Name": "Child", 
     "Children": [], 
     "Parent": { 
     "$ref": "1" 
     } 
    } 
    ], 
    "Parent": null 
} 

但是反序列化不起作用。 Parent屬性返回null。

的測試看起來是這樣的:

[Test] 
public void Test() 
{ 
    var child = new Group("Child"); 
    var parent = new Group("Parent"); 
    parent.AddChild(child); 

    var json = JsonConvert.SerializeObject(parent, Formatting.Indented); 
    Debug.WriteLine(json); 

    var deserializedParent = (Group) JsonConvert.DeserializeObject(json, typeof(Group)); 
    Assert.IsNotNull(deserializedParent.Children.First().Parent); 
} 

我在做什麼錯?任何幫助感謝!

回答

4

使用引用不適用於只有帶參數的構造函數的對象。

Json.NET必須在創建父項之前反序列化所有子值,它需要這些值傳遞給構造函數,因此沒有有效的父項引用可以分配給子項。

2

要擴展James的答案,可以通過爲Json.Net提供一個無參數(默認)構造函數來解決此問題。如果你願意,它可以是私人的,只要你用[JsonConstructor]屬性標記它。

[JsonObject(IsReference = true)] 
class Group 
{ 
    ... 

    [JsonConstructor] 
    private Group() 
    { 
    } 

    public Group(string name) 
    { 
     Name = name; 
     Children = new List<Group>(); 
    } 

    ... 
} 

這種安排允許Json.Net創建對象,而不需要所有的信息;然後它可以使用公共屬性填充事件。

小提琴:https://dotnetfiddle.net/QfqV43