【问题标题】:Parsing XML in C# from SOAP response with header values从带有标头值的 SOAP 响应中解析 C# 中的 XML
【发布时间】:2019-08-14 18:15:45
【问题描述】:

我有一个来自 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 时也很吃力。有什么方法可以忽略标题,只查找与标签匹配的内容?

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

【问题讨论】:

  • 在您的Customer 类中,您有一个code 元素,但这不会映射到带有XmlSerializer 的XML,因为它嵌套在details 元素下。这是一个错误,还是您希望自定义映射一直向下,而不仅仅是跳过标题?
  • 嗨。即使我在下面放置另一个类以具有更正的嵌套层次结构,这仍然会像以前一样抛出错误。 [XmlRoot("customer")] public class Customer{ [XmlElement("details")] public Details Details { get;放; } } 公共类详细信息 { [XmlElement("code")] 公共字符串代码 { 获取;放; } }

标签: c# xml soap


【解决方案1】:

如果您在 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 服务会容易得多,因为您可以自动生成类。

【讨论】:

  • 谢谢。我确实尝试过使用 XDocument 的路线,但我遇到了将其转换为我的对象的问题。如何将 unwrappedResponse 转换为传入的对象?
  • 我还尝试创建一个服务引用,它为我生成了类,但它们仍然抛出错误。我可以看到原始响应回来了,但对象是空的
猜你喜欢
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
  • 2016-09-18
  • 2011-10-05
相关资源
最近更新 更多