73 votes

La sérialisation de membre privé de données

Je suis en train de sérialiser un objet XML qui a un certain nombre de propriétés, dont certaines sont en lecture seule.

public Guid Id { get; private set; }

J'ai marqué la classe [Serializable] et j'ai implémenté l'interface ISerializable.

Ci-dessous le code que j'utilise pour sérialiser mon objet.

public void SaveMyObject(MyObject obj)
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
    TextWriter tw = new StreamWriter(_location);
    serializer.Serialize(tw, obj);
    tw.Close();
}

Malheureusement, il tombe sur la première ligne avec ce message.

InvalidOperationException est non gérée: Incapable de générer une classe temporaire (résultat=1). erreur CS0200: Propriété ou d'indexation 'MyObject.Id' ne peut pas être attribué à -- il est en lecture seule

Si j'ai mis l'Id de la propriété publique, il fonctionne très bien. Quelqu'un peut-il me dire si je suis en train de faire quelque chose, ou au moins si c'est encore possible?

61voto

Marc Gravell Points 482669

Vous pouvez utiliser DataContractSerializer (mais notez que vous ne pouvez pas utiliser les attributs xml - xml des éléments):

using System;
using System.Runtime.Serialization;
using System.Xml;
[DataContract]
class MyObject {
    public MyObject(Guid id) { this.id = id; }
    [DataMember(Name="Id")]
    private Guid id;
    public Guid Id { get {return id;}}
}
static class Program {
    static void Main() {
        var ser = new DataContractSerializer(typeof(MyObject));
        var obj = new MyObject(Guid.NewGuid());
        using(XmlWriter xw = XmlWriter.Create(Console.Out)) {
            ser.WriteObject(xw, obj);
        }
    }
}

Sinon, vous pouvez implémenter IXmlSerializable et de faire tout vous-même - mais cela fonctionne avec XmlSerializer, au moins.

18voto

Isaac Points 181

Ce mec m'a sauvé des heures de travail mise en œuvre de la sérialisation personnalisée approches à ce problème. Réponse courte: Ne pas utiliser d'auto propriétés de lecture/définition. Suivez ce lien.

Espérons que cela aide...

6voto

Stefan Steinegger Points 37073

Vous pouvez utiliser l' System.Runtime.Serialization.NetDataContractSerializer. Il est plus puissant et résout certains problèmes de la classique Sérialiseur Xml.

Notez qu'il existe différents attributs de celui-ci.

[DataContract]
public class X
{
  [DataMember]
  public Guid Id { get; private set; }
}


NetDataContractSerializer serializer = new NetDataContractSerializer();
TextWriter tw = new StreamWriter(_location);
serializer.Serialize(tw, obj);

Edit:

Mise à jour basé sur Marc du commentaire: Vous devriez probablement utiliser System.Runtime.Serialization.DataContractSerializer pour votre cas pour obtenir un nettoyage XML. Le reste du code est le même.

2voto

flalar Points 401

Lire uniquement les champs ne seront pas sérialisé à l'aide de l' XmlSerializer, cela est dû à la nature de l' readonly mot-clé

À partir de MSDN:

Le readonly mot-clé est un modificateur que vous pouvez utiliser sur les champs. Lorsqu'un champ déclaration comporte une readonly modificateur, des affectations dans les champs introduit par la déclaration ne peut se produire dans le cadre de la déclaration ou dans un constructeur de la même classe.

Alors... vous avez assez beaucoup besoin de définir les champs de valeur dans le constructeur par défaut...

0voto

jvenema Points 21499

Ce n'est pas possible avec ce mode de sérialisation (voir les autres commentaires pour les solutions). Si vous voulez vraiment quitter votre sérialisation mode, vous avez à travailler dans le cadre des limites sur ce point. Voir cet exemple:

http://en.allexperts.com/q/VB-NET-3306/Class-Serialization.htm

Esentially, marque de la propriété publique, mais lève une exception si c'est accessible à tout autre moment de la désérialisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X