66

This is one i struggled with for ages so thought I'd document somewhere. (Apologies for asking and answering a question.)

(C# .net 2.0) I had a class that was being serialized by XmlSerializer, I added a new public property however it wasn't being included in the output XML.

It's not mentioned in the docs anywhere I could find, but public properties must have a set as well as a get to be serialized! I guess this is because it assumes that if you're going to serialize then you'll want to deserialize from the same file, so only serializes properties that have both a set and a get.

0

7 Answers 7

109

As mentioned, most properties must have both a getter and setter; the main exception to this is lists - for example:

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

which will work fine; however, if XmlSerializer finds a setter - it demands that it is public; the following will not work:

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

Other reasons it might not serialize:

  • it isn't public with get and set (or is readonly for a field)
  • it has a [DefaultValue] attribute, and is with that value
  • it has a public bool ShouldSerializeFoo() method that returned false
  • it has a public bool FooSpecified {get;set;} property or field that returned false
  • it is marked [XmlIgnore]
  • it is marked [Obsolete]

Any of these will cause it not to serialize

Sign up to request clarification or add additional context in comments.

14 Comments

In some cases, a property that returns a collection doesn't need a set, but it must be initialized in the constructor... It is the case for collections with no public constructor. But this behavior seems a bit inconsistent to me...
It will also not serialize if the property is marked [Obsolete].
Had a getter but no setter...wow that was irritating, appreciate the post.
@user384080 most serializers expect to be used in both directions - i.e. both to serialize and deserialize. If there is no set, it won't be able to recreate the object during deserialization, because it can't assign a value. Now, sometimes serializers can work around this, and sometimes they just serialize it without promising to deserialize; however, XmlSerializer chooses the "ignore the property" approach.
The [Foo]Specified serializer "gotcha" had me stumped. Consuming 3rd party XML, with very bad documentation, which had a AmountPaid public decimal property and AmountPaidSpecified public bool property. The default value for AmountPaidSpecified is false since it's a bool. So, AmountPaid was never getting serialized! By setting the AmountPaidSpecified to true, voila!, AmountPaid gets serialized.
|
7

The point about getter+setter is made in the 3rd paragraph on the "Intro to Xml Serialization" page. It's actually in a call-out box. Can't miss it!

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

(having a little too much fun with Freeimagehosting.net)

6 Comments

ah, you're right that it's there but wrong that you can't miss it :)
I read about a study once, that said people ignore headlines and call out boxes in articles, more often than they ignore the regular text. ?? Counter productive.
@Cheeso : that's right, I never look at the sponsored links in Google search results ;)
I'm curious as to why read-only collections are supported, yet read-only properties are not..?
The image linked in the answer is broken
|
5

Also properties that return null are not serialized!

1 Comment

Ah, but nullable type properties that return null are! I have this here public int? GroupTypeId property which got serialised into this here XML - <GroupTypeId xsi:nil="true" />
5

if you don't want to implement proper Setters (because maybe you are neither wanting to deserialize or change an objects value) you can just use dummy setters like this set { }, so that the XMLSerializer works, but nothing happens if you use the Setter...

i.E.

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

1 Comment

this could potentially be an issue if a junior programmer use this setter property and thinking it's setting the value. Still prefer to have "throw new exception... "
3

And if your class inherits a list and also has its own members, only the elements of the list get serialized. The data present in your class members is not captured. Took some time figuring out this!

1 Comment

Ah, but why? Does anybody know?
3

One more thing to add about serialization of collections:

The XmlSerializer ignores collections of interfaces!

And by that I mean ignore. While you will get an exception for a line like:

public IFoo Foo { get; set; }

you will not get an exception for:

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

Comments

0

You can implement the IXmlSerializer and do the serialization manually, and benefit from serializing properties, and vice versa, deserializing them using constructors / private field assignment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.