c# - 将树序列化为 Json 对象

标签 c# json serialization tree

我有以下类(class):

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 吗?

最佳答案

正如我在评论中所说,您的 TreeNode类被序列化为一个数组,因为它实现了 IEnumerable<TreeNode> .因此,当 TreeNode 时,您将唯一看到的是被序列化,是一个节点的 child 。这些 child (当然)也被序列化为一个数组——一直到最后一个叶节点。叶节点没有子节点,因此被序列化为空数组。这就是为什么您的 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所以序列化程序知道它在序列化 TreeNode 时必须使用你的转换器对象。

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

如果您不使用 Json.NET,我无法确切地告诉您该怎么做,但如果您实现 IDictionary 可能会有所帮助而不是 IEnumerable所以序列化程序知道您正在处理键值对。

关于c# - 将树序列化为 Json 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16294912/

相关文章:

c# - 从剪贴板中获取字符串?没有组装引用吗?

c# - WPF DataGridTextColumn 绑定(bind)不接受小数

javascript - "id"如何使用 JSON 填充 jsTree

JSONArray 将响应 null 元素转换为 "null"

Django Rest Framework 外键序列化

javascript - 跨窗口Javascript : is there a right way?

c# - 如何将当前的aspx页面保存为html

c# - 在哪里写单元测试代码?

java SimpleDateFormat.parse 将 UTC 时间转换为亚洲/香港时间

java - 让子类序列化为父类(super class)的实例?