2009-06-18 7 views
4

J'ai rencontré un problème avec la sérialisation SOAP et il serait intéressant de trouver une réponse. Voici un exemple très simplifié:InvalidOperationException lors de la sérialisation SOAP du type complexe

public void Test() 
{ 
    StringBuilder sb = new StringBuilder(); 
    StringWriter writer = new StringWriter(sb); 

    SoapReflectionImporter importer = new SoapReflectionImporter(); 
    XmlTypeMapping map = importer.ImportTypeMapping(typeof(A)); 
    XmlSerializer serializer = new XmlSerializer(map); 
    serializer.Serialize(writer, new A()); 
} 

[Serializable] 
public class A 
{ 
    public A() 
    { 
     BB = new B(); 
    } 

    public int a; 

    public B BB; 
} 
[Serializable] 
public class B 
{ 
    public int A1 { get; set; } 

    public int A2 { get; set; } 
} 

Si je cours Méthode d'essai() je reçois l'exception suivante: System.InvalidOperationException: Token StartElement in state Epilog would result in an invalid XML document.

apprécierait toute aide.

Répondre

3

Utilisez XmlWriter au lieu de StringWriter et effectuez un writer.WriteStartElement ("root");

Cela fonctionne:

Stream s = new MemoryStream(); 
XmlWriter writer = new XmlTextWriter(s, Encoding.UTF8); 

SoapReflectionImporter importer = new SoapReflectionImporter(); 
XmlTypeMapping map = importer.ImportTypeMapping(typeof(A)); 
XmlSerializer serializer = new XmlSerializer(map); 
writer.WriteStartElement("root"); 
serializer.Serialize(writer, new A()); 

StreamReader sr = new StreamReader(s); 
string data = sr.ReadToEnd(); 
+0

Merci, cela aide. Mais j'ai un autre problème, cette fois avec la désertification. Si je substitue la méthode GetHashCode() dans la classe A et essaie d'accéder à la propriété BB, alors NullReferenceException apparaît pendant la désérialisation. D'une manière ou d'une autre, la propriété BB est égale à 0, mais elle ne devrait pas l'être. –

+0

Pouvez-vous poster votre code de désérialisation? Je vais avoir un regard –

+0

Eh bien, j'ai localisé le problème. Le désérialisateur se comporte de manière assez étrange, il crée une nouvelle instance de classe désérialisée (en appelant le constructeur par défaut), après quoi il définit manuellement tous les champs et propriétés à leurs valeurs par défaut. Cela signifie qu'il définit les propriétés de type référence sur null. Et puis deserializator invoque des méthodes comme GetHashCode() et Equals(). Mais mes propres réalisations de ces méthodes "savent" que les propriétés ne seront jamais nulles. Cela a provoqué l'exception. Je viens de changer le code dans GetHashCode() et Equals(), maintenant ils "savent" que les propriétés peuvent être nulles. Merci pour l'aide! –

5

Juste une note, L'exemple supérieur ne fonctionnera pas si la position du flux n'est pas réglé sur le début du cours d'eau. Comme si:

Stream s = new MemoryStream(); 
XmlWriter writer = new XmlTextWriter(s, Encoding.UTF8); 

SoapReflectionImporter importer = new SoapReflectionImporter(); 
XmlTypeMapping map = importer.ImportTypeMapping(typeof(A)); 
XmlSerializer serializer = new XmlSerializer(map); 
writer.WriteStartElement("root"); 
serializer.Serialize(writer, new A()); 

s.Position = 0; 
StreamReader sr = new StreamReader(s); 
string data = sr.ReadToEnd(); 
+0

Merci, content de continuer à lire. Je recevais une chaîne vide pour les données, mais après avoir vu ça ça marche! –

+0

Life Saver! Cette réponse devrait être acceptée car elle est complète. – Harsh

Questions connexes