求助:C# XmlSerializer反序列化SOAP XML时无法识别Response类型
解决SOAP XML反序列化报错问题
报错原因
报错内容翻译为:InvalidOperationException: 无法识别指定的类型: 名称='Response', 命名空间='http://capi.webservice.wg_base_app.enfinity.wg.com/xsd', 在 <return xmlns='http://capi.basket.webservice.wg_base_app.enfinity.wg.com'>。
核心问题有两个:
- XML里的
<ns:return>节点带xsi:type="ax27:Response"属性,声明该节点实际是指定命名空间下的Response类型,但你的C#实体类ReturnData未与这个XML类型做映射。 - 实体类中错误地用XML前缀(如
ns:、ax27:)作为XmlElement的名称,反序列化只认命名空间URI,不认前缀别名。
修正后的实体类
// 对应<ns:getBasketResponse>根节点 [XmlRoot(ElementName = "getBasketResponse", Namespace = "http://capi.basket.webservice.wg_base_app.enfinity.wg.com")] public class GetBasketResponse { // 对应<ns:return>节点,指定命名空间而非前缀 [XmlElement(ElementName = "return", Namespace = "http://capi.basket.webservice.wg_base_app.enfinity.wg.com")] public ReturnData ReturnData { get; set; } } // 与XML中的ax27:Response类型绑定 [XmlType(TypeName = "Response", Namespace = "http://capi.webservice.wg_base_app.enfinity.wg.com/xsd")] public class ReturnData { // 对应<ax27:costs>节点,指定正确命名空间 [XmlElement(ElementName = "costs", Namespace = "http://capi.webservice.wg_base_app.enfinity.wg.com/xsd")] public List<Cost> Costs { get; set; } } // 与XML中的ax27:Cost类型绑定 [XmlType(TypeName = "Cost", Namespace = "http://capi.webservice.wg_base_app.enfinity.wg.com/xsd")] public class Cost { // 对应<ax27:name>节点,指定正确命名空间 [XmlElement(ElementName = "name", Namespace = "http://capi.webservice.wg_base_app.enfinity.wg.com/xsd")] public string Name { get; set; } }
修正后的反序列化代码
需要跳过SOAP的Envelope和Body节点,直接定位到目标响应节点:
XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); // 定位到<ns:getBasketResponse>节点 XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable); nsManager.AddNamespace("ns", "http://capi.basket.webservice.wg_base_app.enfinity.wg.com"); XmlNode targetNode = doc.SelectSingleNode("//ns:getBasketResponse", nsManager); XmlSerializer serializer = new XmlSerializer(typeof(GetBasketResponse)); using (StringReader reader = new StringReader(targetNode.OuterXml)) { GetBasketResponse result = (GetBasketResponse)serializer.Deserialize(reader); }
关键修正说明
- 用
XmlRoot指定实体类对应XML根节点的名称和命名空间。 - 给
ReturnData和Cost添加XmlType特性,将C#类与XML中通过xsi:type声明的类型绑定,解决类型识别问题。 - 所有
XmlElement特性只写节点原名和命名空间URI,不再使用XML前缀。 - 反序列化时先提取目标响应节点,避免SOAP外层节点干扰根类型匹配。
内容的提问来源于stack exchange,提问作者Benjamin Goyvaerts
相关产品推荐
相关产品推荐

