2010-10-04 25 views
3

Je rencontre ce qui doit être un problème TRÈS SILLY avec le Sérialiseur de contrat de données. Il refuse de travailler. J'essaye juste de sérialiser un objet dans un XmlDocument, cependant je semble frapper un mur.DataContractSerializer - Problèmes

Voici les DataContracts Je souhaite serialise:

[DataContract(Namespace="urn://test", Name = "ServiceFault1")] 
public class ServiceFault 
{ 
    [DataMember()] 
    public int hello { get; set; } 

    [DataMember()] 
    public List<Error> Errors {get; set;} 
} 

[DataContract(Namespace = "urn://test", Name = "Error1")] 
public class Error 
{ 
    [DataMember()] 
    public string ErrorCategoryCode { get; set; } 

    [DataMember()] 
    public string LocalErrorCode { get; set; } 

    [DataMember()] 
    public string Description { get; set; } 
} 

Et la méthode qui fait la sérialisation;

public static XmlDocument Serialize(ServiceFault toSer) 
    { 
     DataContractSerializer ser = new DataContractSerializer(toSer.GetType()); 

     MemoryStream mem = new MemoryStream(); 
     ser.WriteObject(XmlWriter.Create(mem), toSer); 

     XmlDocument tmp = new XmlDocument(); 
     mem.Seek(0, SeekOrigin.Begin); 
     tmp.Load(mem); 

     return tmp; 
    } 

Chaque fois que j'appelle la méthode de sérialisation, le flux de mémoire est toujours vide. J'ai essayé un constructeur de cordes, juste pour voir si quelque chose sortait. Si j'utilise le XmlSerializer cela fonctionne, mais je voudrais comprendre pourquoi le code ci-dessus ne fonctionne pas? Pourquoi le sérialiseur est-il toujours vide?

Merci pour toute aide! TM

+1

Sur votre appel .WriteObject, juste passer dans un flux (comme "mem") - ne pas créer un XmlWriter: 'ser.WriteObject (mem, toSer);' –

+0

@marc_s, que changerait-il? WriteObject va créer un XwlWriter sur le flux en interne de toute façon ... –

+0

@ Thomas Levesque: dans mon cas, ** avec ** le XmlWriter, ça n'a pas marché, sans - ça fonctionne parfaitement ... allez ... –

Répondre

4

Ceci est le code que j'utilise pour sérialiser mes objets et cela semble fonctionner pour moi. Aussi je pense que les attributs de DataContract ne sont pas nécessaires, j'utilise seulement un attribut dans un endroit pour ignorer un membre.

DataContractSerializer serializer = new DataContractSerializer(toSers.GetType()); 
MemoryStream ms = new MemoryStream(); 
serializer.WriteObject(ms, toSer); 
ms.Position = 0; 

string serializedContent; 
using(StreamReader sr = new StreamReader(ms)) 
{ 
    serializedContent = sr.ReadToEnd(); 
} 

Les différences que je vois est que je vous écris directement au MemoryStream, et le réglage de la position à 0, plutôt que d'appeler Seek().

Vous pouvez charger la chaîne résultante dans un XmlDocument si vous le souhaitez, en utilisant XmlDocument.LoadXml sur l'instance.

+0

ms.Position = 0 ..... merci! –

3

Le problème se trouve dans la ligne suivante parce que le XmlWriter n'a pas vidées de son contenu dans le flux de mémoire encore:

ser.WriteObject(XmlWriter.Create(mem), toSer); 

Essayez plutôt en utilisant:

public static XmlDocument Serialize(ServiceFault toSer) 
{ 
    DataContractSerializer ser = new DataContractSerializer(toSer.GetType()); 
    XmlDocument tmp = new XmlDocument(); 
    using (MemoryStream mem = new MemoryStream()) 
    { 
     using (var memWriter = XmlWriter.Create(mem)) 
     { 
      ser.WriteObject(memWriter, toSer); 
     } 

     mem.Seek(0, SeekOrigin.Begin); 
     tmp.Load(mem); 
    } 
    return tmp; 
}