嵌套的json对象不使用Json.NET更新/继承

时间:2015-03-25 12:19:33

标签: c# json

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

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}]]}}"

使用Newtonsoft.Json 6.0.8,父母没有得到"提示"它的孩子得到了一个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":[[]]}"

我做错了什么?

1 个答案:

答案 0 :(得分:3)

问题出现是因为所有JToken个对象都有一个Parent属性,用于记录它们在JSON对象层次结构中的位置 - 但是您试图将JArray Child添加到两个不同的无关的父母。首先将它添加到Children对象(实际上不在您正在创建的JSON对象树中):

        Children.Add("1", Child);

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

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

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

  1. 尝试创建多重父对象时抛出异常,或者
  2. 从上一个父级中删除对象并将其移动到新父级,或者
  3. 在新父级中创建对象的克隆。
  4. 事实证明,它需要选项#3:它将Children["1"]复制到DstParent。我不确定是否记录了这些内容,但是JContainer的{​​{3}}显而易见 - 查找调用InsertItem的{​​{1}}。因此,当您将孙子添加到EnsureParentToken时,您将其添加到原始数组而不是副本。您可以通过添加以下调试代码来看到这一点:

    DstChild

    对此的简单修复是避免创建完全不必要的 Debug.WriteLine(object.ReferenceEquals(DstParent[0], DstChild)); //prints False 对象:

    Children