序列化到树JSON对象 [英] Serializing a Tree into Json Object
问题描述
我有以下类:
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。在这两种情况下,我得到一个输出 -
So, when I have an object of type FolderStructureNode
it is essentially a tree datastructure where each node represents a folder.
I want to serialize this object into a JsonObject. I have tried both - JavaScriptSerializer and NewtonSoft. In both cases I get an output as -
[
[
[]
],
[
[]
],
[]
]
在序列化的时候,树看起来是这样的:
At the time of serialization, the tree looks something like this:
我如何序列化,以获得正确的JSON对象?我必须遍历树并创建JSON自己?
How do I serialize it in order to get the correct json object? Do I have to traverse the tree and create the json myself?
推荐答案
正如我在我的评论说,你的树节点
类序列化为一个数组,因为它实现的IEnumerable<&树节点GT;
。所以,你永远不会看到当树节点
是序列化的唯一的事,是一个节点的孩子。这些孩子也序列化为一个数组(当然) - 到最后的叶节点。叶节点没有孩子,因此被序列化为空数组。所以这就是为什么你的JSON输出看起来像这样
As I said in my comment, your TreeNode
class is serialized as an array because it implements IEnumerable<TreeNode>
. So the only thing you will ever see when a TreeNode
is serialized, are the children of a node. These children are (of course) also serialized as an array - down to the last leaf node. The leaf nodes don't have children and are therefore serialized as empty arrays. So that's why your JSON output looks like this.
您没有明确指定你想要的JSON输出到有,但我想你想要的是这样的:
You didn't exactly specify what JSON output you want to have, but I think what you want is like this:
{
"Sales Order": { },
"RFP":
{
"2169": { }
},
"Purchase Order":
{
"2216": { }
}
}
要做到这一点,你的树节点
类必须作为连载的对象的。在我看来,(假定/建议你使用Newtonsoft Json.NET),你应该写一个自定义的转换器类可能是这样的:
To achieve this, your TreeNode
class must be serialized as object. In my opinion (and assuming/suggesting you're using Newtonsoft Json.NET), you should write a custom converter class which might look like this:
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);
}
}
然后,你必须来装饰你的树节点
类的<code> JsonConverterAttribute 所以串行知道它有使用你的转换器序列化时,树节点$ 。C $ C>对象
Then you have to decorate your TreeNode
class with the JsonConverterAttribute
so the serializer knows that it has to use your converter when serializing a TreeNode
object.
[JsonConverter(typeof(TreeNodeConverter))]
public class TreeNode : IEnumerable<TreeNode>
{
// ...
}
如果您不要用Json.NET,我不能确切地告诉你该怎么做,但它可能会帮助你将实施的IDictionary
而不是的IEnumerable
所以串行知道你要处理的键 - 值对。
If you don't use Json.NET, I can't exactly tell you what to do but it might help if you would implement IDictionary
instead of IEnumerable
so the serializer knows you're dealing with key-value-pairs.
这篇关于序列化到树JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!