Click here to Skip to main content
15,884,986 members
Articles / Programming Languages / XML
Tip/Trick

Get rid of XmlInclude when using XmlSerializer

Rate me:
Please Sign up or sign in to vote.
3.80/5 (7 votes)
29 Jul 2011CPOL1 min read 68.5K   4   3
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Baruch2314-Sep-12 15:27
professionalBaruch2314-Sep-12 15:27 
QuestionFor deep and complex class structures Pin
Bob Sandberg29-Jul-11 4:49
Bob Sandberg29-Jul-11 4:49 
AnswerRe: For deep and complex class structures Pin
Daniel Gidman1-Aug-11 5:39
professionalDaniel Gidman1-Aug-11 5:39 

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

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