2017-05-02 1 views
10

Lorsque j'appelle une opération de service Web, WCF désérialise le message à la classe proxy avec DataContractSerializer: pourquoi ne puis-je pas faire la même chose?Comment désérialiser un message de réponse de savon WCF à partir d'un fichier avec DataContractSerializer?

Voici le message de savon dans le fichier ActLoginResponse.xml:

<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> 

Le code proxy WCF pour la classe ActLoginResponse correspondante est:

[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; 
    } 
} 

donc je dois analyser le XML à un instance d'objet de type ActLoginResponse.

Voici comment je réalise l'analyse syntaxique:

 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); 

L'objet actLogin est créé, mais le contenu est actLogin.return AllWays NULL! Ai-je manqué quelque chose ?

+0

Avez-vous les propriétés de la classe LoginResponseType définie? Si ce n'est pas le cas, il ne pourra pas désérialiser les valeurs du fichier XML vers l'objet. – Popo

+0

Oui, toutes les propriétés sont définies car LoginResponseType est une classe générée lors de la référence du WSDL en tant que service. Lorsque j'utilise le service Web, LoginResponseType est désérialisé à partir des réponses SOAP reçues du réseau. Je veux faire la même chose à partir d'un fichier. – abreneliere

+0

Quelle est la réponse d'un appel de service Web client wcf *? Voulez-vous dire une réponse du service WCF? –

Répondre

2

Vous devriez pouvoir utiliser XmlSerializer pour accomplir ceci avec l'aide de SoapReflectionImporter.

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; 

La classe SoapReflectionImporter fournit des correspondances de type à parties de message codé SOAP, tel que défini dans un Web Services Description document Langue (WSDL). Il est utilisé uniquement lorsqu'un service Web ou un client spécifie le codage SOAP, comme décrit dans la section 5 de la spécification SOAP 1.1 .

La commande suivante a été utilisée pour générer vos contrats clients de WSDL

SvcUtil.exe IPlotiservice.wsdl /t:code /serviceContract 
3

je WSDL que vous aviez fourni de l'autre question et créé une classe proxy de celui-ci.

Utilisation du XML ci-dessus, il me semble avoir aucun problème désérialisation dans le ActLoginResponse par ce qui suit:

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()); 

reference