使用 Json.Net 分析两个语义相同的层次结构文档并失败



我有两个JSON文档,它们代表相同的层次结构和内容。我可以看到这两个文档之间的唯一区别是键值对的顺序不同。一个文档按我的预期解析,而另一个则不然。

我正在使用"保留引用处理",因此节点应引用其父节点。(测试中的变量"hierarchyTwoNode"是未设置其 Parent 属性的文档(。我包括了一个测试(可以在这里找到(来证明这一点。 以下是工作 JSON 的简化版本:

{
  "Root": {
    "$id": "1",
    "Id": "1472459628771017730",
    "Type": "cras",
    "Content": {
      "Name": "lorem"
    },
    "Parent": null,
    "Children": [
      {
        "$id": "2",
        "Id": "1472459628812960771",
        "Type": "morbi",
        "Content": {
          "Name": "ipsum dolor"
        },
        "Parent": {
          "$ref": "1"
        }
      }
    ]
  }
}

还有失败的 JSON:

{
  "Root": {
    "Parent": null,
    "$id": "1",
    "Children": [
      {
        "Parent": {
          "$ref": "1"
        },
        "$id": "2",
        "Content": {
          "Name": "ipsum dolor"
        },
        "Type": "morbi",
        "Id": "1472459628812960771"
      }
    ],
    "Content": {
      "Name": "lorem"
    },
    "Type": "cras",
    "Id": "1472459628771017730"
  }
}

有人可以告诉我正在发生的事情吗?

有人可以告诉我正在发生的事情吗?

本质上,正在发生的事情是,在其中一个 JSON 字符串上,元数据属性放置在第一个实际属性之后

所有$xxx属性都是元数据,必须放在对象/子对象的开头。

此限制的原因如下:

如果我们查看 JSON.Net 的内部结构,在执行元数据查找时,我们可以看到,一旦我们读取不是元数据的属性,我们就会停止元数据查找。

我只能做出公平的假设,即如果 JSON 文件非常大,它用于计算和内存优化。

若要使代码正常工作,只需将$开头的所有属性放在对象的开头,它应该像一个超级按钮一样工作。

正如Salvalai正确推断@Fabio的那样,Json.Net 通常希望任何元数据属性(如$id$type(首先出现在每个对象中,以获得最佳的反序列化效率。如果元数据没有首先出现,则 Json.Net 假定它不存在。这就是为什么在重新排序属性时会得到不同的结果。

幸运的是,Json.Net 提供了一个MetadataPropertyHandling设置,以允许它处理这种情况。 如果将MetadataPropertyHandling设置为ReadAhead它应该可以解决您的问题。 请注意,如果 JSON 很大,这可能会对性能产生影响。

JsonSerializerSettings settings = new JsonSerializerSettings
{
    MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
};
var hierarchyOne = JsonConvert.DeserializeObject<Hierarchy>(HierarchyOne, settings);
var hierarchyTwo = JsonConvert.DeserializeObject<Hierarchy>(HierarchyTwo, settings);

相关内容

  • 没有找到相关文章

最新更新