从JSON子代创建父代

时间:2018-10-09 08:40:29

标签: c# json.net

我有这样的JSON子代/树表示:

{
    "someObj": 
    {
        "test": 10
    },
    "children": 
        [
          {
            "someObj": 
            {
                "test": 11
            },
            "children": 
                [
                   {
                      "someObj": 
                         {
                           "test": 12,
                           "children": null
                         }
                   }
               ]
           },
        {
            "someObj": 
               {
                  "test": 12
               },
            "children": 
                [
                   {
                    "someObj": 
                        {
                          "test": 13,
                          "children": null
                        }
                   }
                ]
        }
    ]
}

我正在将其反序列化为C#类表示形式:

public class Example
    {
        public Dictionary<string, object> SomeObj { get; set; }
        public IList<Example> Children { get; set; }
        //Extended with Parent prop
        public Example Parent { get; set; }
    }

我想做的是使用Example属性扩展我的模型类ParentParent应包含有关“上一个”子对象的所有信息-示例:"someObj: { "test": 11 }知道其父对象为"someObj": { "test": 10 }

我应该写一些JsonConverter来实现吗?或者在反序列化之后执行某种方法,该方法将在所有嵌套的(子级)对象并创建其父对象之后循环?

2 个答案:

答案 0 :(得分:2)

据我所知,设置JSON转换来做到这一点并不容易。您可以滚动自己的转换器来为您完成此操作,但是它可能给表带来额外的复杂性,使它不值得进行任何工作。

或者,您可以后处理该结构。由于您已经定义了层次结构(通过Children),因此现在遍历层次结构来引用父级也就不难了。

这可以通过一种相当简单的递归方法来完成:

public void RegisterParentRecursive(Example parent)
{
    foreach(var child in parent.Children)
    {
        child.Parent = parent;
        RegisterParentRecursive(child);
    }
}

您只需在顶级父级上调用它即可

Example topLevelParent = ParseMyJSON();

RegisterParentRecursive(topLevelParent);

由于这是一个内存过程,因此不会成为性能消耗。

此外,对于足够大的结构使遍历不那么琐碎,我希望您会首先遇到其他问题(JSON字符串大小,反序列化性能,...),因此并没有真正使后处理本身最大的瓶颈。

答案 1 :(得分:0)

使用json转换事件OnDeserialized很方便——你的后期处理会自动开始。 像这样:

public class Example
{
    public Dictionary<string, object> SomeObj { get; set; }
    public IList<Example> Children { get; set; }
    //Extended with Parent prop
    public Example Parent { get; set; }

    [OnDeserialized]
    protected void OnDeserializedMethod(StreamingContext context)
    {
        RegisterParentRecursive(this);
    }

    public void RegisterParentRecursive(Example parent)
    {
        foreach (var child in parent.Children)
        {
            child.Parent = parent;
            RegisterParentRecursive(child);
        }
    }

}