使用HttpClient使用SOAP服务

时间:2017-10-13 16:09:50

标签: c# xml web-services soap httpclient

我遇到了来自SOAP响应的数组的反序列化问题。它返回null,但作为响应,我实际上可以看到正确的xml消息。也许有人可以看到我的代码中出现了什么问题。提前谢谢。

SOAP响应:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns-wp="imcwp" xmlns:ns-hostax="imchostax" xmlns:ns-ilms="imcilms" xmlns:ns-qtms="imcqtms" xmlns:ns-tptms="imctptms">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns-wp:strTrailerRequest-TrailerResponse>
         <ns-wp:Trailer>
            <ns-wp:TrailerId>T001</ns-wp:TrailerId>
            <ns-wp:TrailerType>Flat Extender</ns-wp:TrailerType>
         </ns-wp:Trailer>
         <ns-wp:Trailer>
            <ns-wp:TrailerId>T002</ns-wp:TrailerId>
            <ns-wp:TrailerType>Flat Extender</ns-wp:TrailerType>
         </ns-wp:Trailer>
         <ns-wp:Trailer>
            <ns-wp:TrailerId>T003</ns-wp:TrailerId>
            <ns-wp:TrailerType>Flat Extender</ns-wp:TrailerType>
         </ns-wp:Trailer>
      </ns-wp:strTrailerRequest-TrailerResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

响应模型:

[XmlRoot(ElementName = "strTrailerRequest-TrailerResponse", Namespace = "imcwp")]
public class strTrailerRequestTrailerResponse
{
    [XmlArray("strTrailerRequest-TrailerResponse", Namespace = "imcwp")]
    [XmlArrayItem("Trailer", Namespace = "imcwp")]
    public List<Trailer> Trailers { get; set; }
}

解析方法:

    private strTrailerRequestTrailerResponse ParseTrailerResponse(string response)
    {
        var soap = XDocument.Parse(response);
        XNamespace ns = "imcwp";

        var trailerResponseNode = soap.Descendants(ns + "strTrailerRequest-TrailerResponse").FirstOrDefault().ToString();
        var result = Deserialize<strTrailerRequestTrailerResponse>(trailerResponseNode);

        return result;
    }

2 个答案:

答案 0 :(得分:1)

为什么不只是对整个对象进行deserilize,在这种情况下你不需要xDocument和查询:

var envelop = Deserialize<Envelope>(response);
foreach (var strTrailerRequestTrailerResponseTrailer in envelop.Body.strTrailerRequestTrailerResponse)
{

}

和yr反序列化方法:

public static T Deserialize<T>(string response)
{
    var serializer = new XmlSerializer(typeof(T));
    using(TextReader reader = new StringReader(response))
    {
        return (T)serializer.Deserialize(reader);
    }
}

如果你仍然希望使用XDocument,那么你可以使用Deserialize方法和我定义的相同。如果你不尝试:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "imcwp")]
public partial class strTrailerRequestTrailerResponseTrailer
{
    public string TrailerId { get; set; }

    public string TrailerType { get; set; }
}

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "imcwp")]
[System.Xml.Serialization.XmlRootAttribute("strTrailerRequest-TrailerResponse", Namespace = "imcwp", IsNullable = false)]
public partial class strTrailerRequestTrailerResponse
{
    [System.Xml.Serialization.XmlElementAttribute("Trailer")]
    public strTrailerRequestTrailerResponseTrailer[] Trailer { get; set; }
}

答案 1 :(得分:0)

对于简单的xml,您可以使用xml linq。请参阅以下代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace Certificate
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);
            XDocument doc = XDocument.Parse(xml);

            XElement soap = doc.Root;
            XNamespace ns = soap.GetNamespaceOfPrefix("ns-wp");


            List<Trailer> trailers = doc.Descendants(ns + "Trailer").Select(x => new Trailer()
            {
                trailerId = (string)x.Element(ns + "TrailerId"),
                trailerType = (string)x.Element(ns + "TrailerType")
            }).ToList();
        }

    }
    public class Trailer
    {
        public string trailerId { get; set; }
        public string trailerType { get;set;}

    }
}