使用XmlDictionaryReader反序列化soap消息

时间:2018-03-29 09:18:39

标签: c# soap

我正在尝试反序列化SOAP消息

<?xml version="1.0" encoding="UTF-8" standalone="no"?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
  <ns3:findContractResponse xmlns:ns3="http://somewebsite.com/soapService">
    <return>123</return>
    <return>456</return>
  </ns3:findContractResponse>
</S:Body></S:Envelope>

这是代码

using (Stream rs = response.GetResponseStream())
{
    using (var reader = XmlReader.Create(rs))
    {
        Message m = Message.CreateMessage(reader, int.MaxValue, MessageVersion.Soap11WSAddressing10);
        XmlDictionaryReader dr = m.GetReaderAtBodyContents();
        DataContractSerializer dcs1 = new DataContractSerializer(typeof(findContractResponse), "findContractResponse", "http://somewebsite.com/soapService");
        findContractResponse fcr1 = (findContractResponse)dcs1.ReadObject(dr);
        long[] contracts1 = fcr1.@return;
    }
}

fcr1正确设置为findContractResponse对象,但fcr1。@ return为NULL而不是长数列表。我在这做错了什么?这是从wsdl:

生成的findContractResponse
[System.Diagnostics.DebuggerStepThroughAttribute()]    
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="findContractResponse", WrapperNamespace="http://schemas.datacontract.org/2004/07/wsdltest.testHttpsClient", IsWrapped=true)]
public partial class findContractResponse {
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace= "http://schemas.datacontract.org/2004/07/wsdltest.testHttpsClient", Order=0)]
    [System.Xml.Serialization.XmlElementAttribute("return", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public long[] @return;

    public findContractResponse() {
    }

    public findContractResponse(long[] @return) {
        this.@return = @return;
    }
}

1 个答案:

答案 0 :(得分:0)

经过几天的尝试,我发现了一种愚蠢的方式。我发布我的解决方案以防万一有人可能需要这个。

var response = (HttpWebResponse)httpRequest.GetResponse();
using (Stream rs = response.GetResponseStream())
{
    findContractResponse result = DeserializeResponse<findContractResponse>(rs);
    return result == null ? null : result.@return;
}

T DeserializeResponse<T>(Stream stream)
{
    using (StreamReader reader = new StreamReader(stream))
    {
        Type type = typeof(T);
        XDocument doc = XDocument.Parse(reader.ReadToEnd());
        XElement data = doc.Descendants(XName.Get(type.Name, "http://somewebsite.com/soapService")).FirstOrDefault();
        if(data == null)
        {
            return default(T);
        }

        XmlSerializer ser = new XmlSerializer(type, "http://somewebsite.com/soapService");
        string tmpXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + data.ToString();
        using (StringReader stringReader = new StringReader(tmpXml))
        {
            return (T)ser.Deserialize(stringReader);
        }
    }
}