嵌套的json对象不会使用Json.NET更新/继承 [英] nested json objects dont update / inherit using Json.NET

查看:112
本文介绍了嵌套的json对象不会使用Json.NET更新/继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用折旧的System.Json,我得到了我期望的结果(来自Javascript): 孩子得到一个孙子,所有父母都知道...

Using the depreciated System.Json, I get the Result I expect (coming from Javascript): The Child gets a GrandChild and all the Parents know about it...

var Parents         = new JsonObject();
var Children        = new JsonObject();

var Parent          = JsonArray.Parse("[]");
Parents.Add("1", Parent);

var Child           = JsonArray.Parse("[]");
Children.Add("1", Child);

var DstParent       = (JsonArray)Parents["1"];
DstParent.Add(Children["1"]);


var DstChild    = (JsonArray)Children["1"];
JsonObject GrandChild   = (JsonObject)JsonArray.Parse("{}");
GrandChild.Add("Age", 15);
DstChild.Add(GrandChild);

var Result = Parents.ToString();

给我:"{" 1:[[{" Age:15}]]}"

Gives me: "{"1":[[{"Age":15}]]}"

使用Newtonsoft.Json 6.0.8,父级"没有得到提示",即孩子生了一个孙子.

Using Newtonsoft.Json 6.0.8, The Parent is not getting the "hint" that it's Child got a GrandChild.

var Parents         = new JObject();
var Children        = new JObject();

var Parent          = JArray.Parse("[]");
Parents.Add("1", Parent);

var Child           = JArray.Parse("[]");
Children.Add("1", Child);

var DstParent       = (JArray)Parents["1"];
DstParent.Add(Children["1"]);


var DstChild    = (JArray)Children["1"];
var GrandChild  = JObject.Parse("{}");
GrandChild.Add("Age", 15);
DstChild.Add(GrandChild);

给我:"{" 1:[[]]}"

Gives me: "{"1":[[]]}"

我在做什么错了?

推荐答案

出现问题是因为所有 Parent 属性,以记录其在JSON对象层次结构中的位置-但您正在尝试将JArray Child添加到两个不同的 unrelated 父级.首先,将其添加到Children对象(实际上不在您创建的JSON对象树中):

The problem arises because all JToken objects have a Parent property which records their location in the JSON object hierarchy -- but you are trying to add your JArray Child to two different unrelated parents. First you add it to the Children object (which is not actually in the tree of JSON objects you are creating):

        Children.Add("1", Child);

接下来,将其添加到DstParent数组(在创建的JSON对象树中,):

Next you add it to the DstParent array (which is in the tree of JSON objects you are creating):

        DstParent.Add(Children["1"]);

那么,在这种情况下,Json.NET会做什么?它可以:

So, what does Json.NET do in this case? It could either:

  1. 抛出异常,试图创建一个多父对象,或者
  2. 将对象从其上一个父对象中移除,然后将其移至新的父对象,或者
  3. 在对象的新父对象中创建一个克隆.

事实证明,它带有选项#3:它将Children["1"]复制到DstParent.我不确定是否记录或记录在何处,但是可以从

As it turns out, it takes option #3: it copies Children["1"] into DstParent. I'm not sure if or where this is documented, but it's apparent from the source code for JContainer - look for InsertItem which calls EnsureParentToken. Thus when you add your grandchild to DstChild you are adding it to the original array not the copy. You can see this by adding the following debug code:

        Debug.WriteLine(object.ReferenceEquals(DstParent[0], DstChild)); //prints False

最简单的解决方法是避免创建完全不需要的Children对象:

The simple fix for this is to avoid creating the Children object which is completely unnecessary anyway:

        var parentObj = new JObject();

        var parentArray = new JArray();
        parentObj.Add("1", parentArray);

        var childArray = new JArray();
        parentArray.Add(childArray);

        var grandChild = new JObject();
        grandChild.Add("Age", 15);
        childArray.Add(grandChild);

这篇关于嵌套的json对象不会使用Json.NET更新/继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆