2009-02-22 16 views
46

To jest ten, z którym zmagałem się przez wieki, więc pomyślałem, że gdzieś dokumentuję. (Przepraszam za zadawanie i odpowiadanie na pytanie.)Dlaczego moja publiczna właściwość nie jest serializowana przez XmlSerializer?

(C# .net 2.0) Miałem klasę, która była serializowana przez XmlSerializer, dodałem nową właściwość publiczną, jednak nie została ona uwzględniona w wynikowym kodzie XML.

Nie jest to wspomniane w dokumentach, gdziekolwiek można znaleźć, ale właściwości publiczne muszą mieć zestaw, a także uzyskać serialowanie! Sądzę, że dzieje się tak dlatego, że zakłada się, że jeśli zamierzasz serializować, będziesz chciał deserializować z tego samego pliku, więc tylko serializuje właściwości, które mają zarówno zestaw, jak i get.

Odpowiedz

76

Jak wspomniano, większość właściwości musi mieć zarówno getter, jak i ustawiający; głównym wyjątkiem jest lista - na przykład:

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

która będzie działać poprawnie; jednak, jeśli XmlSerializerstwierdza, że ​​ jest ustawiaczem - żąda, aby było publiczne; dodaje się nie praca:

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

Inne powody to może nie serializacji:

  • to nie jest publiczny z get i set (lub jest readonly na polu)
  • ma atrybutu [DefaultValue] i ma tę wartość:
  • ma publiczną metodę bool ShouldSerializeFoo(), która zwróciła wartość false
  • ma publicznego bool FooSpecified {get;set;} własności lub pole, które zwracane fałszywe
  • jest oznaczony [XmlIgnore]
  • jest oznaczony [Obsolete]

Każda z nich spowoduje, że nie będzie szeregować

+0

Mimo, że mam pewne właściwości z tylko dostać. Są one również oznaczone atrybutami XmlArray i XmlArrayItem, więc domyślam się, że właśnie dlatego unikają zestawu. – Rory

+2

W niektórych przypadkach właściwość, która zwraca kolekcję, nie wymaga zestawu, ale musi zostać zainicjowana w konstruktorze ... Dotyczy to kolekcji bez publicznego konstruktora. Ale to zachowanie wydaje mi się nieco niespójne ... –

+0

Nigdy tego nie zauważyłem, dzięki Thomas; Zbadam ;-p –

7

punktu o getter + setera dokonuje się w trzecim akapicie na stronie "Intro to Xml Serialization". W rzeczywistości jest w polu wywoływania. Nie można tego przegapić!

Intro-to-XML Serialization http://www.freeimagehosting.net/uploads/2f04fea2db.png

(mający trochę zbyt dużo zabawy z Freeimagehosting.net)

+0

ah, masz rację, że jest tam, ale źle, że nie możesz tego przegapić :) – Rory

+0

Czytałem kiedyś o badaniu, że ludzie ignorują nagłówki i wywołują pola w artykułach, częściej niż ignorują zwykły tekst. ?? Licznik produktywny. – Cheeso

+0

@Cheeso: tak, nigdy nie patrzę na sponsorowane linki w wynikach wyszukiwania Google;) –

4

również właściwości, które zwracają wartość null nie są w odcinkach!

+1

Ah, ale właściwości typu null, które zwracają wartość null są! Mam to tutaj publiczne int? Właściwość GroupTypeId, która została spersonalizowana pod tym adresem XML - Jon

2

Jeśli twoja klasa dziedziczy listę, a także ma swoich członków, to tylko jej elementy są serializowane. Dane obecne w twoich członkach klasy nie są przechwytywane. Trochę czasu zajęło mi zrozumienie tego!

+0

Ah, ale dlaczego? Czy ktoś wie? – almcnicoll

5

jeśli nie chcesz zaimplementować odpowiednich Seterów (ponieważ być może nie chcesz ani deserializować, ani zmieniać wartości obiektów), możesz po prostu użyć ustawników manekinów, takich jak ten set { }, aby XMLSerializer działał, ale nic się nie dzieje, jeśli użyj Settera ...

iE

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

może to być problem, jeśli młodszy programista używa tej właściwości ustawiającej i myśli, że ustawia wartość. Nadal wolę mieć "nowy wyjątek ..." – user384080

1

Jeszcze jedna rzecz dodać o serializacji zbiorów:

XmlSerializer ignoruje zbiory interfejsów!

I przez to rozumiem ignorować. Podczas gdy dostaniesz wyjątek dla linii takich jak:

public IFoo Foo { get; set; } 

będzie nie uzyskać wyjątek dla:

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

Można wdrożenia IXmlSerializer i wykonaj serializacji ręcznie, a korzyści z szeregowania właściwości i odwrotnie, deserializacja ich przy użyciu konstruktora/prywatnego przypisania pola.

Powiązane problemy