C# 中实现XML字符串转换为类对象时出现异常的问题咨询
C# XML反序列化异常修复方案
触发运行异常的核心原因
- 目标XML根节点绑定了自定义命名空间
urn:microsoft-dynamics-nav/xmlports/x14027120,类定义未同步声明该命名空间的映射关系。XmlSerializer会严格校验命名空间匹配度,不匹配时直接抛出反序列化异常。 - 类成员定义不符合XmlSerializer的序列化规则:
- 原
WdashboardRoot类中的Whsedashboard1成员未实现属性访问器(get/set),属于语法不完整的公共字段,无法被XmlSerializer识别为可序列化目标。 - 原代码将
Whsedashboard1定义为数组类型,但示例XML中下直接挂载单个 节点,无嵌套两层同名字节的结构。数组类型的默认序列化规则会匹配“外层同名节点包裹内层同名单元素节点”的嵌套结构,和实际XML结构完全错位。
- 原
调整步骤与可运行代码
- 修正根类的XML映射关系,添加
XmlRoot特性指定匹配的节点名和对应命名空间 - 补全类成员的属性访问器,根据实际XML结构调整成员类型:
- 若XML中仅存在单个
节点,直接将成员定义为单个 Whsedashboard1类型 - 若XML中存在多个平级的
节点,添加 XmlElement特性标记列表成员,消除数组嵌套结构的默认匹配偏差
- 若XML中仅存在单个
- 原
Serializer封装类的逻辑无问题,无需修改
修正后的完整代码:
using System; using System.IO; using System.Collections.Generic; using System.Xml.Serialization; [Serializable] [XmlRoot(ElementName = "WdashboardRoot", Namespace = "urn:microsoft-dynamics-nav/xmlports/x14027120")] public class WdashboardRoot { // 匹配单个Whsedashboard1节点的场景 public Whsedashboard1 Whsedashboard1 { get; set; } // 多节点场景下替换为以下定义 // [XmlElement(ElementName = "Whsedashboard1")] // public List<Whsedashboard1> WhsedashboardCollection { get; set; } } [Serializable] public class Whsedashboard1 { public string DocumentType { get; set; } public string OrderNumber { get; set; } public string CustomerNo { get; set; } public string CustomerName { get; set; } public string ShippingAgentCode { get; set; } public string ShippingAgentService { get; set; } public string ReqShipmentDate { get; set; } public string PromiseShipmentDate { get; set; } public string Status { get; set; } } public class Serializer { public T Deserialize<T>(string input) where T : class { System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T)); using (StringReader sr = new StringReader(input)) { return (T)ser.Deserialize(sr); } } public string Serialize<T>(T ObjectToSerialize) { XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType()); using (StringWriter textWriter = new StringWriter()) { xmlSerializer.Serialize(textWriter, ObjectToSerialize); return textWriter.ToString(); } } }
附加注意事项
- 示例XML中节点文本前后的多余空格(如
Order、S - ORD101006)不会阻断反序列化流程,会原样保留为属性值。如果需要自动清理首尾空格,可在对应属性的set访问器中添加Trim()处理。 - XmlSerializer对节点名、命名空间的匹配是大小写敏感的,定义类特性时要和XML中的实际值逐字符对齐,避免因为大小写不一致触发匹配失败。
内容的提问来源于stack exchange,提问作者Magento Nav
相关产品推荐
相关产品推荐

