XmlSerializer反序列化SOAP XML返回null问题求助
SOAP XML反序列化后对象为null的排查与解决方法
问题描述
尝试将一段SOAP格式XML反序列化为Envelope类,但反序列化后得到的对象为null。Envelope类是通过Visual Studio「将XML粘贴为类」功能生成的,相关XML与C#代码如下:
SOAP XML内容
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <ns0:vendResponse xmlns:ns0="http://mynamespace.co/ns0"> <ns0:sequence>234532532221</ns0:sequence> <ns0:CId>0</ns0:CId> <ns0:RefId>202675454545453434343</ns0:RefId> <ns0:origAcct>20.00</ns0:origAcct> <ns0:destAcct>00087646564</ns0:destAcct> <ns0:responseCode>0</ns0:responseCode> <ns0:responseMessage>Successful</ns0:responseMessage> </ns0:vendResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
反序列化代码
var contentStream = File.ReadAllText("response.xml"); Envelope resultEnvelope = new Envelope(); using (var stringReader = new StringReader(contentStream)) { using (XmlReader reader = new XmlTextReader(stringReader)) { var serializer1 = new XmlSerializer(typeof(Envelope)); resultEnvelope = serializer1.Deserialize(reader) as Envelope; } }
核心原因与解决方法
反序列化返回null的主要原因是类的XML特性与XML中的命名空间不匹配,Visual Studio自动生成的类可能未正确绑定SOAP和业务数据的命名空间,导致序列化器无法识别XML节点。
1. 修正自动生成的类的XML特性
手动调整Envelope及嵌套类的XmlRoot、XmlElement特性,确保命名空间与XML完全一致:
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; } } public class Body { [XmlElement(ElementName = "vendResponse", Namespace = "http://mynamespace.co/ns0")] public VendResponse VendResponse { get; set; } } public class VendResponse { [XmlElement(ElementName = "sequence", Namespace = "http://mynamespace.co/ns0")] public string Sequence { get; set; } [XmlElement(ElementName = "CId", Namespace = "http://mynamespace.co/ns0")] public string CId { get; set; } [XmlElement(ElementName = "RefId", Namespace = "http://mynamespace.co/ns0")] public string RefId { get; set; } [XmlElement(ElementName = "origAcct", Namespace = "http://mynamespace.co/ns0")] public string OrigAcct { get; set; } [XmlElement(ElementName = "destAcct", Namespace = "http://mynamespace.co/ns0")] public string DestAcct { get; set; } [XmlElement(ElementName = "responseCode", Namespace = "http://mynamespace.co/ns0")] public string ResponseCode { get; set; } [XmlElement(ElementName = "responseMessage", Namespace = "http://mynamespace.co/ns0")] public string ResponseMessage { get; set; } }
2. 优化反序列化代码(可选)
XmlTextReader已被标记为过时,建议替换为XmlReader.Create,同时可以添加错误监听排查潜在问题:
var contentStream = File.ReadAllText("response.xml"); Envelope resultEnvelope = null; var serializer = new XmlSerializer(typeof(Envelope)); // 添加未知节点监听,排查不匹配问题 serializer.UnknownElement += (sender, e) => { Console.WriteLine($"未识别元素: {e.Element.Name},命名空间: {e.Element.NamespaceURI}"); }; serializer.UnknownAttribute += (sender, e) => { Console.WriteLine($"未识别属性: {e.Attr.Name},命名空间: {e.Attr.NamespaceURI}"); }; using (var stringReader = new StringReader(contentStream)) using (var reader = XmlReader.Create(stringReader)) { resultEnvelope = serializer.Deserialize(reader) as Envelope; }
验证方法
运行修正后的代码,若resultEnvelope不再为null,且Body.VendResponse下的属性能正确读取XML中的值,说明问题已解决。
内容的提问来源于stack exchange,提问作者Sola
相关产品推荐
相关产品推荐

