Por que minha propriedade pública não é serializada pelo XmlSerializer?

Este é um com o qual eu lutei durante séculos, então pensei em documentar em algum lugar. (Desculpas por perguntar e responder a uma pergunta.)

(C # .net 2.0) Eu tinha uma class que estava sendo serializada pelo XmlSerializer, adicionei uma nova propriedade pública, mas ela não estava sendo incluída no XML de saída.

Não é mencionado nos documentos em nenhum lugar que eu encontrei, mas as propriedades públicas devem ter um conjunto e também ser serializados! Eu acho que isso é porque ele assume que, se você estiver indo para serializar, então você vai querer desserializar a partir do mesmo arquivo, por isso só serializa as propriedades que têm um conjunto e um get.

Como mencionado, a maioria das propriedades deve ter um getter e setter; a principal exceção a isso é listas – por exemplo:

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

que funcionará bem; no entanto, se o XmlSerializer encontrar um setter, ele exigirá que seja público; o seguinte não funcionará:

 public List Bar {get; private set;} // FAIL 

Outras razões que podem não ser serializadas:

  • não é público com get e set (ou é readonly para um campo)
  • tem um atributo [DefaultValue] e está com esse valor
  • ele tem um método bool ShouldSerializeFoo() que retornou false
  • tem um bool FooSpecified {get;set;} público bool FooSpecified {get;set;} propriedade ou campo que retornou false
  • está marcado [XmlIgnore]
  • está marcado [Obsolete]

Qualquer um deles fará com que não serialize

O ponto sobre getter + setter é feito no terceiro parágrafo na página ” Introdução à serialização de XML “. Na verdade, está em uma checkbox de chamada. Não pode perder!

Serialização Intro-to-XML http://sofpt.miximages.com/c%23/www.freeimagehosting.net

(Divirta-se um pouco demais com Freeimagehosting.net)

se você não quiser implementar Setters apropriados (porque talvez você não queira desserializar ou alterar um valor de objects), pode usar apenas set { } fictícios como este set { } , para que o XMLSerializer funcione, mas nada acontece se você usar o Setter …

iE

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

Também as propriedades que retornam nulo não são serializadas!

E se sua class herdar uma lista e também tiver seus próprios membros, somente os elementos da lista serão serializados. Os dados presentes nos membros da sua turma não são capturados. Demorou algum tempo para descobrir isso!

Mais uma coisa para adicionar sobre serialização de collections:

O XmlSerializer ignora collections de interfaces!

E com isso quero dizer ignorar . Enquanto você receberá uma exceção para uma linha como:

 public IFoo Foo { get; set; } 

você não receberá uma exceção para:

 public ICollection LotsOfFoos { get { return this.fooBackingField; } } 

Você pode implementar o IXmlSerializer e fazer a serialização manualmente e se beneficiar das propriedades de serialização e vice-versa, desserializando-as usando a atribuição de construtores / campos privados.