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 消息反序列化到该(生成的)类中?
我不知道 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);
}