2013-04-30 52 views
2

我有以下類別:序列化樹成JSON對象

TreeNode.cs

public class TreeNode : IEnumerable<TreeNode> 
{ 
    public readonly Dictionary<string, TreeNode> _children = new Dictionary<string, TreeNode>(); 

    public readonly string Id; 
    public TreeNode Parent { get; private set; } 

    public TreeNode(string id) 
    { 
     this.Id = id; 
    } 

    public TreeNode GetChild(string id) 
    { 
     return this._childs[id]; 
    } 

    public void Add(TreeNode item) 
    { 
     if (item.Parent != null) 
     { 
      item.Parent._childs.Remove(item.Id); 
     } 

     item.Parent = this; 
     this._childs.Add(item.Id, item); 
    } 

    public IEnumerator<TreeNode> GetEnumerator() 
    { 
     return this._childs.Values.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 

    public int Count 
    { 
     get { return this._childs.Count; } 
    } 
} 

FolderStructureNode.cs

public class FolderStructureNode : TreeNode 
{ 
    //Some properties such as FolderName, RelativePath etc. 
} 

所以,當我有一個對象類型爲FolderStructureNode它實質上是一個樹形數據結構,其中每個節點代表一個文件夾。 我想將這個對象序列化成一個JsonObject。我已經嘗試了兩種 - JavaScriptSerializer和NewtonSoft。在這兩種情況下,我得到一個輸出 -

[ 
    [ 
    [] 
    ], 
    [ 
    [] 
    ], 
    [] 
] 

在序列化的時候,樹看起來是這樣的:

Tree

如何序列化,以獲得正確的JSON目的?我是否必須遍歷樹並自己創建json?

+0

我認爲序列化程序查看對象的屬性,所以請嘗試在屬性中包裝_childs字典。 – Christian 2013-04-30 08:29:53

+1

問題是你的'TreeNode'類實現'IEnumerable ',因此序列化器會將你的節點序列化爲一個數組(你的情況爲空)。如果沒有看到你的'IEnumerable'實現代碼,我不知道它爲什麼是空的。 – fero 2013-04-30 08:32:00

+0

我已經添加了整個TreeNode類。 – mridula 2013-04-30 08:41:39

回答

1

正如我在我的評論中所說的,你的TreeNode類被序列化爲一個數組,因爲它實現了IEnumerable<TreeNode>。因此,當一個TreeNode被序列化時,你唯一會看到的是一個節點的子節點。這些孩子(當然)也被序列化爲一個數組 - 直到最後一個葉節點。葉節點沒有子節點,因此被序列化爲空數組。所以這就是爲什麼你的JSON輸出看起來像這樣。

你沒有確切指定你想擁有什麼JSON輸出,但我想你想要的是這樣的:

{ 
    "Sales Order": { }, 
    "RFP": 
    { 
     "2169": { } 
    }, 
    "Purchase Order": 
    { 
     "2216": { } 
    } 
} 

要做到這一點,您TreeNode類必須序列化爲對象。在我看來(假定/建議你使用Newtonsoft Json.NET),你應該寫一個自定義的轉換器類,它可能是這樣的:

class TreeNodeConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     // we can serialize everything that is a TreeNode 
     return typeof(TreeNode).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     // we currently support only writing of JSON 
     throw new NotImplementedException(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     // we serialize a node by just serializing the _children dictionary 
     var node = value as TreeNode; 
     serializer.Serialize(writer, node._children); 
    } 
} 

然後,你必須來裝點你TreeNode類的JsonConverterAttribute如此串行器知道它在序列化一個對象時必須使用你的轉換器。

[JsonConverter(typeof(TreeNodeConverter))] 
public class TreeNode : IEnumerable<TreeNode> 
{ 
    // ... 
} 

如果你不使用Json.NET,我不能確切地告訴你做什麼,但它可能會幫助,如果你將實現IDictionary代替IEnumerable所以串行知道你處理鍵 - 值對。

+0

我只是刪除IEnumerable,因爲它不是真的需要..它現在工作..非常感謝!雖然,我不明白爲什麼數組內的對象沒有被序列化。 – mridula 2013-04-30 10:08:57

+0

他們確實被序列化了。但是它們被序列化爲包含子節點的數組,這些節點也被序列化爲數組等等。所以你不會得到任何東西,但數組。最後的子節點(葉節點)不包含任何子節點,所以它們被序列化爲空數組。它們不能被序列化爲其他任何東西(比如ID),因爲它們必須是數組。 – fero 2013-04-30 10:49:50