将 XML 转换为 .net 中的对象
Posted
技术标签:
【中文标题】将 XML 转换为 .net 中的对象【英文标题】:Converting XML to object in .net 【发布时间】:2021-03-10 01:32:55 【问题描述】:我有一个这种格式的肥皂结果
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<sendSmsResponse xmlns="https://srvc.blablabla.com/SmsProxy">
<sendSmsResult>
<ErrorCode>0</ErrorCode>
<PacketId>90279163</PacketId>
<MessageIdList>
<MessageId>4402101870</MessageId>
<MessageId>4402101871</MessageId>
</MessageIdList>
</sendSmsResult>
</sendSmsResponse>
</soap:Body>
</soap:Envelope>
我想将它转换为一个对象,以便在我的 Windows 服务中使用它。
这是执行此操作的代码:
public static T DeserializeInnerSoapObject<T>(string soapResponse)
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(soapResponse);
var soapBody = xmlDocument.GetElementsByTagName("sendSmsResponse")[0];
string innerObject = soapBody.InnerXml;
XmlSerializer deserializer = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(innerObject))
return (T)deserializer.Deserialize(reader);
以下是我为该流程创建的类:
[XmlRoot(ElementName = "sendSmsResult", Namespace ="https://srvc.blablabla.com/SmsProxy")]
public class sendSmsResult
public string ErrorCode get; set;
public string PacketId get; set;
public MessageId[] MessageIdList get; set;
public class MessageId
[XmlElement(ElementName = "MessageId", Namespace = "https://srvc.blablabla.com/SmsProxy")]
public string messageId get; set;
在服务中,我把上面的方法称为
var result = DeserializeInnerSoapObject<sendSmsResult>(test);
结果为@987654327@ 和PacketId
返回正确的值,为MessageIdArray
返回正确的MessageIds
数量,但MessageIds
为空。
我对@987654332@ 做错了吗?
任何帮助表示赞赏。
【问题讨论】:
您没有自动生成的服务/客户端存根吗?您使用的是 WCF 还是第 3 方 Soap 服务? 另见:***.com/a/4304356/982149,也许更好:***.com/a/14360303/982149 您如何期望 C# 中的MessageIdArray
将映射到 XML 中的 MessageIdList
?您要么需要为 C# 变量提供相同的名称,要么设置一个属性来告诉 XmlSerializer 哪个 XML 元素用于该属性。
无论如何,您不一定需要服务文档。只要它发布 WSDL(SOAP 服务应该这样做),您就可以让 Visual Studio 自动生成您需要的 C# 类。这是菲尔多(和丹尼斯)的观点。
^^ ADyson 所说的。顺便说一句,现在我希望一个体面的 SOAP-Servive 提供商能够为至少最常用的平台和语言提供现成的客户端库。 :/ 如果不是 protobuf / gRPC 替代方案。
【参考方案1】:
当我遇到这样的问题时,我喜欢做的是逆向处理。因此,创建一个 SendSmsResult 对象并填充属性。然后序列化对象查看生成的xml。这将向您展示您的代码将创建一个看起来像这样的 xml
<?xml version="1.0" encoding="utf-16"?>
<sendSmsResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="https://srvc.blablabla.com/SmsProxy">
<MessageIdList>
<MessageId>
<MessageId>11</MessageId>
</MessageId>
</MessageIdList>
</sendSmsResult>
MessageId 元素过多。
如果您将课程更新为:
[XmlRoot(ElementName = "sendSmsResult", Namespace = "https://srvc.blablabla.com/SmsProxy")]
public class sendSmsResult
public string ErrorCode get; set;
public string PacketId get; set;
[XmlArrayItem("MessageId", IsNullable = false)]
public List<string> MessageIdListget;set;
它将起作用,您的属性将被正确的数据填充。
【讨论】:
以上是关于将 XML 转换为 .net 中的对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 .Net 2.0/C# 中将 StreamReader 转换为 XMLReader 对象