2011-05-25 3 views
4

Je reçois l'exception suivante lorsque j'essaie de désérialiser un message soap. Je le fais de cette façon parce que j'ai les fichiers de réponses que je veux réutiliser dans les tests. Je ne peux pas utiliser un service réel ou similaire, car il ne correspond pas à l'architecture du cadre de test que nous avons.Impossible de désérialiser un message SOAP par programme

Test 'MyUnitTestMethod' failed: System.InvalidOperationException : There is an error in XML document (1, 2). 
----> System.InvalidOperationException : <MySpecialResponse xmlns='http://xsd.com/msgs/v1'> was not expected. 
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) 
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) 
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream) 


private const string _content = 
@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""> 
    <soapenv:Body> 
    <ns3:MySpecialResponse xmlns:ns3=""http://xsd.com/msgs/v1"" > 
     <header> 
     <status>0</status> 
     </header> 
     <ns3:Payload> 
     <ns3:CustomerName>name</ns3:CustomerName> 
     <ns3:EmailAddress>[email protected]</ns3:EmailAddress> 
     </ns3:Payload> 
    </ns3:MySpecialResponse> 
    </soapenv:Body> 
</soapenv:Envelope>"; 

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://xsd.com/msgs/v1")] 
public partial class MySpecialResponse : BaseResponse { 

    private MySpecialPayload payloadField; 

    /// <remarks/> 
    public MySpecialPayload Payload { 
     get { 
      return this.payloadField; 
     } 
     set { 
      this.payloadField;= value; 
     } 
    } 
} 

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://xsd.com/msgs/v1")] 
public partial class MySpecialPayload { 

    private string customerNameField; 

    private string emailAddressField; 

    /// <remarks/> 
    public string CustomerName { 
     get { 
      return this.customerNameField; 
     } 
     set { 
      this.customerNameField = value; 
     } 
    } 

    /// <remarks/> 
    public string EmailAddress { 
     get { 
      return this.emailAddressField; 
     } 
     set { 
      this.emailAddressField = value; 
     } 
    } 
} 

//The code I am using - might not be right? 
    var serialiser = new System.Xml.Serialization.XmlSerializer(typeof(MySpecialResponse)); 


    using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(_content)) 
    { 
     var doc = new System.Xml.XmlDocument(); 
     doc.Load(stream); 

     var nsManager = new System.Xml.XmlNamespaceManager(doc.NameTable); 
     nsManager.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); 

     //so I can get the actual response and not the soap body 
     var node = doc.SelectSingleNode("//soapenv:Body", nsManager); 

     if (node != null) 
     { 
      byte[] xml = Encoding.UTF8.GetBytes(node.InnerXml); 
      using (var memStream = new System.IO.MemoryStream(xml)) 
      { 
       memStream.Position = 0; 
       var resp = (MySpecialResponse)serialiser.Deserialize(memStream); //Throws exception here 
      } 
     } 
    } 

(BaseResponse a le champ d'en-tête)

Toutes les idées me l'exception se soulevait et comment je peux obtenir le message de savon pour désérialiser le message dans l'objet que ce soit réparait mon code ou appliquer une autre La technologie.

Note: J'ai beaucoup de fichiers que je veux ue une méthode générique de désérialisation, donc je ne saurai pas à l'avance tous les espaces de noms xml, seulement le type de réponse racine.

Merci

+0

Puis-je demander pourquoi auriez-vous besoin d'analyser les messages SOAP manuellement comme celui-ci? –

+0

J'ai un cadre qui crée manuellement des réponses dans le code. Nous avons les fichiers de réponses de notre client que je veux utiliser dans certaines circonstances. – aqwert

+0

S'il y a un moyen plus facile/meilleur où je reçois les fichiers de réponse de savon et de désérialiser cela fonctionne, je vais utiliser cela. – aqwert

Répondre

8

Ok, j'ai résolu pour moi-même.

je devais ajouter le XmlRootAttribute pour le XmlSerializer

var xRoot = new System.Xml.Serialization.XmlRootAttribute(); 
xRoot.ElementName = "MySpecialResponse"; 
xRoot.IsNullable = true; 
xRoot.Namespace = rootResponseNamespace; 

var serialiser = new System.Xml.Serialization.XmlSerializer(typeof(MySpecialResponse), xRoot); 
Questions connexes