C#对象转Json再转Xml反序列化后数组为空原因及错误咨询
问题原因
- 核心原因是JSON转XML生成的节点名和
XmlSerializer反序列化要求的节点名不匹配:
使用Newtonsoft.Json的DeserializeXmlNode方法转换JSON数组时,会默认将数组的子元素节点命名为item,你可以打印生成的xmlString验证,生成的XML结构大致如下:
而<House> <Objects json:Array="true"> <item> <Name>Name1</Name> </item> <item> <Name>Name2</Name> </item> </Objects> </House>XmlSerializer反序列化House类的Objects属性(类型为MyObject[])时,默认期望数组的子元素节点名称和元素类名一致,也就是MyObject,无法识别item节点,因此直接忽略这些节点,最终得到的Objects属性为空。 - 次要影响因素:你序列化JSON时开启了
TypeNameHandling.Objects,生成的JSON会携带$type类型元数据,转换为XML后会变成带特殊前缀的属性,XmlSerializer不会处理这些额外元数据,但这不是导致数组为空的核心原因。
操作存在的错误
- 没有考虑Newtonsoft.JSON转XML的默认数组节点命名规则,和.NET内置
XmlSerializer的序列化规则不一致的问题,缺少对应适配配置。 - 额外引入了JSON→XML→对象的多层转换链路,不仅增加了出错概率,也存在不必要的性能开销,如果不需要XML中间结果,直接用JSON反序列化得到
House对象即可。
修复方案
方案1:给数组属性加特性适配节点名
在House类的Objects属性上添加[XmlElement("item")]特性,指定XmlSerializer识别item作为数组子元素名:
public class House { [XmlElement("item")] public MyObject[] Objects { get; set; } }
方案2:转换XML后重命名节点
生成XML之后,遍历所有item节点,重命名为MyObject,再做反序列化。
方案3:省略XML转换链路
如果不需要保留XML中间结果,直接用Newtonsoft.Json反序列化JSON字符串得到House对象:
House house2 = JsonConvert.DeserializeObject<House>(json, jsonSerializerSettings);
内容的提问来源于stack exchange,提问作者Daniele Mereu
相关产品推荐
相关产品推荐

