web-dev-qa-db-fra.com

Pourquoi ma propriété publique n'est-elle pas sérialisée par XmlSerializer?

C'est celui avec lequel j'ai lutté pendant des siècles, alors j'ai pensé documenter quelque part. (Toutes mes excuses pour avoir posé et répondu à une question.)

(C # .net 2.0) J'avais une classe qui était sérialisée par XmlSerializer, j'ai ajouté une nouvelle propriété publique mais elle n'était pas incluse dans le XML de sortie.

Ce n'est pas mentionné dans les documents où que je puisse trouver, mais les propriétés publiques doivent avoir un ensemble ainsi qu'un get pour être sérialisés! Je suppose que c'est parce qu'il suppose que si vous allez sérialiser, vous voudrez désérialiser à partir du même fichier, donc ne sérialiser que les propriétés qui ont à la fois un ensemble et un get.

56
Rory

Comme mentionné, la plupart des propriétés doivent avoir à la fois un getter et un setter; la principale exception est les listes - par exemple:

private readonly List<Foo> bar = new List<Foo>();
public List<Foo> Bar {get { return bar; } } // works fine

qui fonctionnera bien; cependant, si XmlSerializer trouve un passeur - il exige qu'il soit public; ce qui suit pas fonctionnera:

public List<Foo> Bar {get; private set;} // FAIL

Autres raisons pour lesquelles il peut ne pas sérialiser:

  • il n'est pas public avec get et set (ou est readonly pour un champ)
  • il a un attribut [DefaultValue] et est avec cette valeur
  • il a une méthode publique bool ShouldSerializeFoo() qui a renvoyé false
  • il a une propriété ou un champ public bool FooSpecified {get;set;} qui a renvoyé false
  • il est marqué [XmlIgnore]
  • il est marqué [Obsolete]

L'un de ces éléments l'empêchera de sérialiser

88
Marc Gravell

Le point sur getter + setter est fait dans le 3ème paragraphe de la page " Intro to Xml Serialization ". C'est en fait dans une boîte de légende. À ne pas manquer!

Sérialisation d'introduction à XML http://www.freeimagehosting.net/uploads/2f04fea2db.png

(s'amuser un peu trop avec Freeimagehosting.net)

7
Cheeso

si vous ne voulez pas implémenter des Setters appropriés (parce que vous ne voulez peut-être pas non plus désérialiser ou modifier la valeur d'un objet), vous pouvez simplement utiliser des setters factices comme celui-ci set { }, pour que le XMLSerializer fonctionne, mais rien ne se passe si vous utilisez le Setter ...

c'est à dire.

public string ID { get { return _item.ID.ToString(); } set { } }
5
JonSchn

De plus, les propriétés qui renvoient null ne sont pas sérialisées!

4
anonymous

Une dernière chose à ajouter sur la sérialisation des collections:

Le XmlSerializer ignore les collections d'interfaces!

Et par cela, je veux dire ignorer. Vous obtiendrez une exception pour une ligne comme:

public IFoo Foo { get; set; }

vous n'obtiendrez pas une exception pour:

public ICollection<IFoo> LotsOfFoos { get { return this.fooBackingField; } }
2
NobodysNightmare

Et si votre classe hérite d'une liste et a également ses propres membres, seuls les éléments de la liste sont sérialisés. Les données présentes dans les membres de votre classe ne sont pas capturées. Il a fallu du temps pour comprendre cela!

2
Nanda

Vous pouvez implémenter le IXmlSerializer et effectuer la sérialisation manuellement, et bénéficier des propriétés de sérialisation, et vice versa, en les désérialisant à l'aide des constructeurs/affectation de champ privé.

0
Shimmy