带命名空间的XML反序列化为C#对象时出现未预期节点报错如何解决
错误含义
该报错是因为你定义的XML根节点特性配置不符合C# XmlSerializer的规则,和实际XML结构不匹配:
你当前在XmlRoot特性里把节点前缀、命名空间声明都直接写在了节点名称参数里,而XmlSerializer解析XML时会自动将pippo前缀映射到对应的命名空间http://pippoonboarding.eu,实际识别到的根节点是命名空间下的Response节点,和你配置的节点名称完全不匹配,所以抛出节点未预期的错误。
除此之外你现有的类定义还有两个隐性问题也会导致后续反序列化失败:
- 所有子节点都带有
pippo前缀,和根节点属于同一个命名空间,你没有给子节点指定对应命名空间的映射 - 部分属性类型和XML实际值不匹配,比如
CompanyResponse.ResponseCode的值为字符串OK/KO,但你定义为了int类型;空自闭合节点直接映射到int类型也会抛出转换错误。
修复步骤
- 修正Root类的XmlRoot特性,拆分节点名称和命名空间配置,同时删除多余的
Response属性:
[Serializable, XmlRoot(ElementName = "Response", Namespace = "http://pippoonboarding.eu")] public class Root { [XmlElement(ElementName = "Header")] public Header Header { get; set; } [XmlElement(ElementName = "CompanyResponse")] public CompanyResponse CompanyResponse { get; set; } }
- 给所有子节点对应的类添加
XmlType特性,统一指定命名空间,同时修正属性类型不匹配的问题:
[XmlType(Namespace = "http://pippoonboarding.eu")] public class Header { public string FileId { get; set; } public string SenderId { get; set; } public string ProcessingDate { get; set; } public string ProcessingTime { get; set; } public string ResponseCode { get; set; } } [XmlType(Namespace = "http://pippoonboarding.eu")] public class CompanyResponse { public string SellerId { get; set; } // 空节点映射用可空类型避免报错 public int? SellerContractCode { get; set; } public int? VATNumber { get; set; } // 修正为字符串类型匹配OK/KO的返回值 public string ResponseCode { get; set; } public int? PippoCompanyCode { get; set; } public ResponseDetails ResponseDetails { get; set; } } [XmlType(Namespace = "http://pippoonboarding.eu")] public class ResponseDetails { public string Entity { get; set; } public string ProgressiveNumber { get; set; } public string PippoShopCode { get; set; } public string TerminalId { get; set; } public string FieldName { get; set; } public string ErrorType { get; set; } public string ErrorCode { get; set; } public string ErrorDescription { get; set; } }
内容的提问来源于stack exchange,提问作者Fabio V.
相关产品推荐
相关产品推荐

