Почему моя публичная собственность не сериализуется XmlSerializer? - PullRequest
55 голосов
/ 22 февраля 2009

Это тот, с которым я боролся целую вечность, поэтому думал, что я где-нибудь запишу. (Извиняюсь за вопрос и ответ на вопрос.)

(C # .net 2.0) У меня был класс, который сериализовал XmlSerializer, я добавил новое открытое свойство, однако оно не было включено в выходной XML.

В документах это нигде не упоминается, но публичные свойства должны иметь как набор, так и сериализацию! Я предполагаю, что это потому, что предполагается, что если вы собираетесь сериализовать, то вы захотите десериализовать из того же файла, поэтому сериализует только свойства, которые имеют как набор, так и получение.

Ответы [ 7 ]

88 голосов
/ 22 февраля 2009

Как уже упоминалось, большинство свойств должны иметь как геттер, так и сеттер; главное исключение - списки - например:

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

, который будет работать нормально; однако, если XmlSerializer находит установщик - он требует, чтобы он был открытым; следующее не работает:

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

Другие причины, по которым он может не сериализоваться:

  • это не публично с get и set (или * readonly для поля)
  • имеет атрибут [DefaultValue] и имеет это значение
  • у него есть публичный bool ShouldSerializeFoo() метод, который вернул false
  • имеет общедоступное bool FooSpecified {get;set;} свойство или поле, которое вернуло false
  • помечено [XmlIgnore]
  • помечено [Obsolete]

Любое из них приведет к тому, что оно не будет сериализовано

7 голосов
/ 09 марта 2009

Смысл о getter + setter описан в третьем абзаце на странице " Intro to Xml Serialization ". Это на самом деле в поле вызова. Не могу пропустить это!

Сериализация от XML к XML http://www.freeimagehosting.net/uploads/2f04fea2db.png

(слишком много веселья с Freeimagehosting.net)

5 голосов
/ 08 августа 2012

если вы не хотите реализовывать правильные сеттеры (потому что, возможно, вы не хотите десериализовать или изменять значение объектов), вы можете просто использовать фиктивные сеттеры, подобные этому set { }, чтобы XMLSerializer работал, но ничего произойдет, если вы используете Сеттер ...

И.Э. ​​

public string ID { get { return _item.ID.ToString(); } set { } }
4 голосов
/ 28 июня 2009

Также свойства, которые возвращают ноль, не сериализуются!

2 голосов
/ 12 сентября 2014

Еще одна вещь, которую нужно добавить о сериализации коллекций:

XmlSerializer игнорирует наборы интерфейсов!

И под этим я подразумеваю игнорировать . Пока вы получите исключение для строки вроде:

public IFoo Foo { get; set; }

вы не получите исключение для:

public ICollection<IFoo> LotsOfFoos { get { return this.fooBackingField; } }
2 голосов
/ 17 апреля 2012

И если ваш класс наследует список, а также имеет свои собственные члены, только элементы списка сериализуются. Данные, присутствующие в ваших учениках, не фиксируются. Потребовалось время, чтобы понять это!

0 голосов
/ 10 октября 2014

Вы можете реализовать IXmlSerializer и выполнить сериализацию вручную, извлечь выгоду из сериализации свойств и наоборот, десериализовав их, используя конструкторы / присвоение частного поля.

...