Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Get rid of XmlInclude when using XmlSerializer

0.00/5 (No votes)
29 Jul 2011 1  
A solution presented in C# .NET 3.5 using the latest in LINQ technology.

Ever tried to serialize a class using XmlSerializer and bumped into an exception telling you to use XmlInclude? Well, this tip will use Reflection to automatically dispel such problems.


Using the XmlInclude attribute on a base class to recognize its derived classes is somewhat problematic as it goes against principles of Object Oriented programming in which base classes are not supposed to know of their derived classes. It tends to be high maintenance because new derived classes may appear long after the base class is written. Also, it may be the case that the programmer doesn't even have access to change the base class to add support for his newly written derived class.


So, here is the solution, presented in C# .NET 3.5 using the latest in LINQ technology.


Let's say you have three base classes named Car, Wheel, and Door. From these three classes, a big tree of derived classes might grow. This code will allow you to use the default XmlSerializer without using XmlInclude and without any kind of config files or whatever.


C#
// use reflection to get all derived types
var knownTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
    t => typeof(Car).IsAssignableFrom(t) || typeof(
    Wheel).IsAssignableFrom(t) || typeof(Door).IsAssignableFrom(t)).ToArray();

// prepare to serialize a car object
XmlSerializer serializer = new XmlSerializer(typeof(Car), knownTypes);

// serialize!
TextWriter textWriter = new StreamWriter(@"car.xml", false, Encoding.UTF8);
serializer.Serialize(textWriter, car);
textWriter.Close();

To run this in .NET 2.0, you need to replace the LINQ part with a foreach loop, and the 'var' statement with the real variable type. So the first lines would look like this:


C#
// use reflection to get all derived types
List<type> knownTypes = new List<type>();
foreach(Type t in Assembly.GetExecutingAssembly().GetTypes())
    if (typeof(Car).IsAssignableFrom(t) || 
        typeof(Wheel).IsAssignableFrom(t) ||
        typeof(Door).IsAssignableFrom(t))
       knownTypes.Add(t);

// prepare to serialize a car object
XmlSerializer serializer = new XmlSerializer(typeof(Car), knownTypes.ToArray());

// the rest is same...</type></type>

That is it!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here