Click here to Skip to main content
Click here to Skip to main content

Tagged as

Get rid of XmlInclude when using XmlSerializer

, 29 Jul 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
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.

// 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:

// 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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Yoel Schejter

United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmemberBaruch2314-Sep-12 16:27 
QuestionFor deep and complex class structures PinmemberBob Sandberg29-Jul-11 5:49 
AnswerRe: For deep and complex class structures PinmemberDaniel Gidman1-Aug-11 6:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 29 Jul 2011
Article Copyright 2010 by Yoel Schejter
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid