如何将 WCF Soap 消息反序列化到生成的类中

问题描述 投票:0回答:1

Soap 响应消息:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="urn:stef">
   <soap:Body>
      <tns:ConvertResponse>
         <tns:Result>abc</tns:Result>
      </tns:ConvertResponse>
   </soap:Body>
</soap:Envelope>

生成的代码,由 VS 在添加服务引用时生成(snippet):

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName = "ConvertResponse", WrapperNamespace = "urn:stef", IsWrapped = true)]
public partial class ConvertResponse
{

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace = "urn:stef", Order = 0)]
    public string Result;

    public ConvertResponse()
    {
    }

    public ConvertResponse(string Result)
    {
        this.Result = Result;
    }
}

我使用以下通用代码将此肥皂字符串反序列化为

ConvertResponse
对象:

private static T Deserialize<T>(string xml)
{
    var stream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
    var message = Message.CreateMessage(XmlReader.Create(stream), int.MaxValue, MessageVersion.Soap11);
    var importer = new SoapReflectionImporter(new SoapAttributeOverrides(), "urn:stef");
    var mapping = importer.ImportTypeMapping(typeof(T));
    var xmlSerializer = new XmlSerializer(mapping);

    return (T)xmlSerializer.Deserialize(message.GetReaderAtBodyContents());
}

上述解决方案基于https://stackoverflow.com/a/43901543/17218587

但这不起作用,因为

ConvertResponse
类没有 Result
public
属性,所以这就是反序列化后
Result
为 null 的原因。

所以我的问题是是否有办法将此 xml-soap 消息反序列化到该(生成的)类中?

c# wcf soap deserialization xml-deserialization
1个回答
0
投票

我不知道 Stef Heyenrath 是否得到了这个问题的答案,但这里的问题是,SoapReflectionImporter 和 XmlSerializer 旨在与标有 XmlSerializerFormat 的消息一起使用。但是,由于它有 MessageContract,我们也不能使用 DataContractSerializer。

我还需要反序列化消息,在谷歌中进行了大量的摆弄后,在这里找到了答案:WCF DataContractSerializer 不获取合约属性......为什么不呢?

所以,根据 blowdart,你的代码将是这样的:

private static T Deserialize<T>(string xml, bool useXml)
{
    var stream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
    var message = Message.CreateMessage(XmlReader.Create(stream), int.MaxValue, MessageVersion.Soap11);

    TypedMessageConverter converter = null;

    if (useXml)
        converter = TypedMessageConverter.Create(typeof(T), "*", string.Empty, new XmlSerializerFormatAttribute());
    else
        converter = TypedMessageConverter.Create(typeof(T), "*", string.Empty, new DataContractFormatAttribute());

    return (T)converter.FromMessage(message);
}
© www.soinside.com 2019 - 2024. All rights reserved.