我从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太费劲了。有什么办法可以忽略标题,而只是寻找与标签匹配的内容?
我不想直接进行映射,因为我希望此调用是通用的,因此我可以传递任何请求以及希望将响应映射到的相应对象。
答案 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服务会容易得多,因为您随后可以自动生成类。