使用标头值从SOAP响应中解析C#中的XML

时间:2019-08-14 18:15:45

标签: c# xml soap

我从Web服务收到xml响应,该响应具有一堆我想忽略的标头。 xml看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
  <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
    <ns2:retrieveCustomerResponse xmlns:ns2="http://ws.blah.neeg.com/">
     <customer>
        <details>
           <code>1000274</code>
             <customerNo>1000274</customerNo>
               <customerTypeRef>
                 <code>C</code>

我还有一个对象,我也想映射它,就像这样:

[XmlRoot("customer")]
public class Customer{
    [XmlElement("code")]
    public string Code { get; set; }

当我尝试使用以下方法将xml强制转换为对象时:

public static T CallWebService<T>(string req)
{
  ...calls web service and gets a response
  string soapResult;
  using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
    {
      using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
        {
          soapResult = rd.ReadToEnd();
        }
    }

但是当我尝试将其强制转换为传入的对象类型时:

XmlSerializer serializer = new XmlSerializer(typeof(T));
T returnObject = default(T);

try
  {
    using (TextReader reader = new StringReader(soapResult))
      {
        returnObject = (T)serializer.Deserialize(reader);
      }
   }
   catch (Exception ex)
   {
     Console.WriteLine(ex);
   }

   return returnObject;

我发现一个例外:

There is an error in XML document (1, 24). ---> System.InvalidOperationException: <Envelope xmlns='http://schemas.xmlsoap.org/soap/envelope/'> was not expected.

我认为为模型添加注释会匹配元素,但是看起来解析XML太费劲了。有什么办法可以忽略标题,而只是寻找与标签匹配的内容?

我不想直接进行映射,因为我希望此调用是通用的,因此我可以传递任何请求以及希望将响应映射到的相应对象。

1 个答案:

答案 0 :(得分:0)

如果将响应流而不是字符串加载到XDocument中,则可以使用LINQ to XML查询XML。这样,您可以跳过父元素并访问客户元素,并将其序列化为对象。

    XDocument soapResult;
    using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
    {
        using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
        {
            soapResult = XDocument.Load(rd);
        }
    }

    //should be modified to your needs
    var unwrappedResponse = soapResult.Descendants((XNamespace)"http://schemas.xmlsoap.org/soap/envelope/" + "Body").First().FirstNode; 

如果您使用服务引用或至少可以访问XSD,那么使用SOAP Web服务会容易得多,因为您随后可以自动生成类。

相关问题