Why isn't my public property serialized by the XmlSerializer?

C#.NetXml Serialization

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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

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

Solution 3 - C#

Also properties that return null are not serialized!

Solution 4 - C#

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 { } }

Solution 5 - C#

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!

Solution 6 - C#

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; } }

Solution 7 - C#

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRoryView Question on Stackoverflow
Solution 1 - C#Marc GravellView Answer on Stackoverflow
Solution 2 - C#CheesoView Answer on Stackoverflow
Solution 3 - C#anonymousView Answer on Stackoverflow
Solution 4 - C#JonSchnView Answer on Stackoverflow
Solution 5 - C#NandaView Answer on Stackoverflow
Solution 6 - C#NobodysNightmareView Answer on Stackoverflow
Solution 7 - C#Shimmy WeitzhandlerView Answer on Stackoverflow