将Web Service返回的SOAP XML反序列化为对象时出现XML文档错误的排查求助
解决SOAP XML反序列化错误的问题
你的反序列化报错和XML声明无关(那个标准声明反序列化器会自动处理,不用在模型里配置),主要是几个关键配置和类型匹配问题,咱们一步步梳理:
1. 命名空间配置不匹配
你的SOAP XML里的<soap:Envelope>和<soap:Body>都属于http://schemas.xmlsoap.org/soap/envelope/命名空间,但原模型类没有正确指定这个命名空间;同时ConvertToTypeResponse属于http://tempuri.org/命名空间,原模型的相关配置也有偏差。
2. 错误把命名空间声明当成普通属性
XML里的xmlns:soap、xmlns:xsd、xmlns:xsi是命名空间声明,不是元素的属性,不需要用[XmlAttribute]定义,反序列化器会自动处理这些声明,原模型里的Soap、Xsi、Xsd属性完全多余,反而会导致匹配失败。
3. 数据类型不兼容
XML里的ConvertToTypeResult值是8959459395,这个数值远大于C#中int类型的最大值(2147483647),用int类型接收会触发转换错误,必须改成long类型。
修正后的模型类代码
using System.Xml.Serialization; [XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] public class Envelope { [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] public Body Body { get; set; } // 可选:如果后续需要序列化生成SOAP XML,可保留此字段处理命名空间前缀,反序列化时可省略 [XmlNamespaceDeclarations] public XmlSerializerNamespaces Namespaces { get; set; } = new XmlSerializerNamespaces(); } public class Body { [XmlElement(ElementName = "ConvertToTypeResponse", Namespace = "http://tempuri.org/")] public ConvertToTypeResponse ConvertToTypeResponse { get; set; } } [XmlRoot(ElementName = "ConvertToTypeResponse", Namespace = "http://tempuri.org/")] public class ConvertToTypeResponse { [XmlElement(ElementName = "ConvertToTypeResult", Namespace = "http://tempuri.org/")] public long ConvertToTypeResult { get; set; } // 改为long类型适配大数值 }
验证反序列化代码
你的反序列化逻辑无需修改,使用修正后的模型类即可正常解析XML响应:
IRestResponse response = _client.Execute(_request); var c = response.Content; if (response.IsSuccessful) { XmlSerializer serializer = new XmlSerializer(typeof(Envelope)); using (StringReader reader = new StringReader(c)) { var test = (Envelope)serializer.Deserialize(reader); // 现在可正常访问test.Body.ConvertToTypeResponse.ConvertToTypeResult } }
内容的提问来源于stack exchange,提问作者Qudus
相关产品推荐
相关产品推荐

