3

私は次のクラスを持っています:

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 の両方を試しました。どちらの場合も、次のような出力が得られます-

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

シリアル化の時点で、ツリーは次のようになります。

木

正しいjsonオブジェクトを取得するためにシリアル化するにはどうすればよいですか? ツリーをたどって json を自分で作成する必要がありますか?

4

2 に答える 2

3

コメントで述べたように、TreeNodeクラスは を実装しているため、配列としてシリアル化されIEnumerable<TreeNode>ます。TreeNodeしたがって、aがシリアライズされたときに表示される唯一のものは、ノードの子です。これらの子も (もちろん) 配列としてシリアル化されます (最後のリーフ ノードまで)。リーフ ノードには子がないため、空の配列としてシリアル化されます。そのため、JSON 出力は次のようになります。

必要な JSON 出力を正確に指定しませんでしたが、必要なものは次のようになると思います。

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

これを実現するには、クラスをobjectTreeNodeとしてシリアル化する必要があります。私の意見では (そして、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クラスを で装飾する必要があります。JsonConverterAttributeTreeNode

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

Json.NET を使用しない場合、何をすべきかを正確に伝えることはできませんが、キーと値のペアを扱っていることをシリアライザーが認識できるように、IDictionary代わりに実装すると役立つ場合があります。IEnumerable

于 2013-04-30T09:18:23.110 に答える