Json.NET XML 转换和 TypeNameHandling.Arrays
Posted
技术标签:
【中文标题】Json.NET XML 转换和 TypeNameHandling.Arrays【英文标题】:Json.NET XML conversion and TypeNameHandling.Arrays 【发布时间】:2014-07-27 15:14:15 【问题描述】:眼前的问题
在使用另一个使用 Json.NET 的库时遇到了这个问题。在将 C# 对象序列化为 JSON 以及在客户端应用程序的另一端反序列化它们时,我们一直在大量使用 TypeNameHandling.Arrays
。
但是,Json.NET 的 XmlNodeConverter
似乎与此设置不匹配,在反序列化 JSON 时抛出错误,例如:
'people':
'$type': 'System.Collections.Generic.List`1[[MyNamespace.Person, MyDll]], mscorlib',
'$values': [
'name': 'Alan'
,
'name': 'Bob'
]
原因
抛出异常是因为 Json.NET 尝试将 $values
解释为字符串属性而不是子节点。当在 XmlNodeConverter.cs:1367 周围的空值上调用 .ToString()
时,我们得到空引用异常。
细化
这里的真正问题可能源于 Json.NET 处理 XML 中的数组的方式:它不会生成如下所示的包装器:
<people json:type="System.Collections.Generic.List`1[[MyNamespace.Person, MyDll]], mscorlib">
<person>
<name>Alan</name>
</person>
<person>
<name>Bob</name>
</person>
</people>
...它可以添加自定义json:type
属性,而是依赖于隐式分组共享相同标签的元素:
<person>
<name>Alan</name>
</item>
<person>
<name>Bob</name>
</item>
这种行为对我未经训练的眼睛来说似乎有点不直观——我希望在 XML 中包含一个父元素,而不是默默地删除。 (这可能也是空数组和单元素数组需要额外工作的原因,这里的许多线程和 Json.NET 论坛中都有记录。)
解决方案..?
这里我转向社区..!
-
您是否知道任何变通方法,也许是一些使两者可以很好地发挥作用的设置?
删除父节点是序列化数组的正确方法是否已达成共识?
【问题讨论】:
您可以随时编写自己的自定义 XmlNodeConverter 以使其按您的意愿工作。 【参考方案1】:我的印象是,您对 JSON.Net 的利用方式没有太多访问权限,因为您提到它被另一个库使用。如果您确实有权访问,则可以考虑诸如反序列化为匿名类型然后添加适当的代码来初始化您的类等选项。 (见:Deserialize json with json.net c#)
JSON.net 文档提到了这一点: http://james.newtonking.com/json/help/index.html?topic=html/ConvertingJSONandXML.htm
“将同一层级的多个同名节点组合成一个数组。”
"如果从 JSON 创建的 XML 与您想要的不匹配,那么您需要对其进行转换 手动。执行此操作的最佳方法是将 JSON 加载到 LINQ to JSON 对象中 像 JObject 或 JArray,然后使用 LINQ 创建一个 XDocument。相反的过程, 使用带有 XDocument 的 LINQ 来创建 JObject 或 JArray,也可以。了解更多 关于在此处将 LINQ to JSON 与 LINQ 一起使用。”
针对您的具体问题:
如果您无法编辑反序列化代码,则没有直接的解决方法可以使反序列化在 JSON.net 中正常工作,数组以这种方式构造。
这两种方法都有效。 Json.NET 倾向于编写 JSON 和 XML,看起来像您可能手动编写的内容,而 .Net 序列化程序旨在确保在 .Net 中再次反序列化时不会丢失数据。一般来说,在任何地方都简单地使用同一个库是理想的——实际上,Json.NET 是一种流行的选择。
【讨论】:
感谢您的详尽回答并尝试直接回答我的两个问题!以上是关于Json.NET XML 转换和 TypeNameHandling.Arrays的主要内容,如果未能解决你的问题,请参考以下文章
xml转换为json格式时,如何将指定节点转换成数组 Json.NET