将 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 为空。

我对@9​​87654332@ 做错了吗?

任何帮助表示赞赏。

【问题讨论】:

您没有自动生成的服务/客户端存根吗?您使用的是 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 对象

将 XML 转换为动态 C# 对象

将XML文件中的内容转换为Json对象

将 vb.net 类对象转换为 vb.net 中的 JSON 字符串

在转换为 XML 之前更改 JSON 对象中的属性名称

将对象转换为 XML 字符串