如何使用DataContractSerializer从文件反序列化WCF soap响应消息?
问题描述:
当我调用Web服务操作时,WCF使用DataContractSerializer将消息反序列化到代理类:为什么我不能这样做?如何使用DataContractSerializer从文件反序列化WCF soap响应消息?
下面是在文件ActLoginResponse.xml SOAP消息:
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:PlotiIntf" xmlns:ns2="urn:PlotiIntf-IPloti" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"/>
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns2:ActLoginResponse>
<return>
<ResultCode>0</ResultCode>
<ResultMessage>Login et password correct.</ResultMessage>
<Acteur>
<Id>IMT_706</Id>
<Nom>IMA PROTECT</Nom>
<Prenom/>
<nbFI>0</nbFI>
<FonctionActeur>TS</FonctionActeur>
<Timeout>30</Timeout>
</Acteur>
<ZneGeoList xsi:nil="true"/>
</return>
</ns2:ActLoginResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
为相应ActLoginResponse类的WCF代理代码是:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="ActLoginResponse", WrapperNamespace="urn:PlotiIntf-IPloti", IsWrapped=true)]
public partial class ActLoginResponse {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=0)]
public Ploti.PlotiClient.LoginResponseType @return;
public ActLoginResponse() {
}
public ActLoginResponse(Ploti.PlotiClient.LoginResponseType @return) {
[email protected] = @return;
}
}
所以我需要的XML解析到ActLoginResponse类型的对象实例。
这里是我完成解析:
ActLoginResponse body;
FileStream stream = new FileStream("Requests\\ActLoginResponse.xml", FileMode.Open);
XmlReader xmlReader = XmlReader.Create(stream);
xmlReader.MoveToContent();
xmlReader.ReadStartElement();
xmlReader.MoveToContent();
xmlReader.ReadStartElement();
xmlReader.MoveToContent();
xmlReader.ReadStartElement();
xmlReader.MoveToContent();
// the the reader is on the element ActLoginResponse (that is confirmed by a Log.Debug(xmlReader.ReadOuterXml());
// I create The DataContractSerializer: exception if nampespace is not specified
DataContractSerializer dataContract = new `DataContractSerializer`(typeof(ActLoginResponse), "ActLoginResponse", "urn:PlotiIntf-IPloti");
ActLoginResponse actLogin = dataContract.ReadObject(xmlReader, true);
的actLogin对象被创建,但内容actLogin.return是百达NULL!我错过了什么 ?
答
在SoapReflectionImporter
的帮助下,您应该可以使用XmlSerializer
来完成此操作。
var importer = new SoapReflectionImporter("urn:PlotiIntf-IPloti");
var mapping = importer.ImportTypeMapping(typeof(ActLoginResponse));
var serializer = new XmlSerializer(mapping);
var response = serializer.Deserialize(reader) as ActLoginResponse;
的SoapReflectionImporter类提供类型映射到 SOAP编码消息部分,如在Web服务描述语言 (WSDL)文件来定义。它仅在Web服务或客户端 指定SOAP编码时使用,如SOAP 1.1 规范的第5节中所述。
下面的命令是用来从WSDL
SvcUtil.exe IPlotiservice.wsdl /t:code /serviceContract
答
生成你的客户合同我用你已经从其它问题提供的WSDL和它创造的代理类。
使用上面的XML,我似乎都没有问题,反序列化到ActLoginResponse
通过如下:
Message m = Message.CreateMessage(XmlReader.Create("C:\\testSvc\\login.xml"), int.MaxValue, MessageVersion.Soap11);
SoapReflectionImporter importer = new SoapReflectionImporter(new SoapAttributeOverrides(), "urn:PlotiIntf-IPloti");
XmlTypeMapping mapp = importer.ImportTypeMapping(typeof(ActLoginResponse));
XmlSerializer xmlSerializer = new XmlSerializer(mapp); //typeof(T), xr
var o = (ActLoginResponse)xmlSerializer.Deserialize(m.GetReaderAtBodyContents());
你所定义的LoginResponseType类的属性?如果不是,那么它将无法将xml中的值反序列化到对象。 – Popo
是的所有属性都已定义,因为LoginResponseType是将WSDL引用为服务时生成的类。当我使用Web服务时,LoginResponseType从网络接收到的SOAP响应中被反序列化。我想从文件中做同样的BU。 – abreneliere
什么是*来自wcf客户端web服务调用的响应*?你的意思是一个WCF服务响应? –