Serializing abstract classes to XML

Digg it: http://digg.com/programming/Serializing_abstract_classes_to_XML_in_c

It is often useful to have abstract classes with several derived types to allow use of strongly typed lists and the such.

For example you might have a DocumentFragment class which is abstract and two concrete classes called TextDocumentFragment and CommentDocumentFragment (this example from Willis).

This allows the creation of a List<DocumentFragment> property which can contain objects only of those two types.

If you attempt to create a WebService that returns this list you get an error but this is easy to get around with the code below....

[Serializable()]
[System.Xml.Serialization.XmlInclude(typeof(TextDocumentFragment))]
[System.Xml.Serialization.XmlInclude(typeof(CommentDocumentFragment))]
public abstract class DocumentFragment {
...}

The XmlInclude attributes tell the class that it might be serialized to those two derived classes.

This generates an attribute in the DocumentFragment element specifying the actual type, as below.

<DocumentFragment xsi:type="TextDocumentFragment">

Any additonal properties specific to the derived class will also be included using this method.

Author Dave Howard

I have been involved in IT development for the last 10 years - a lot of it around desktop applications and telecoms.

Comments

Anonymous said:

This is really handy dave, thanks

18/Jul/2006 09:33 AM

Anonymous said:

This methodology seems to be hiding the true problem and that is an inaccurate implementation of OO design patterns, namely the factory pattern.

Having to change the base class to reference any new factory class is self-defeating.

With a little after-thought, the code can be changed to where any derived type can be associated with the abstract class (through the miracle of interfaces) and no XmlInclude would be required.

I suggest further research into factory patterns which seems to be what you are trying to implement here.

26/Sep/2006 13:36 PM

said:

Thanks for the article. Helped me out.

A quick side-note: It may be necessary to also specify a namespace for the abstract class, if the derived classes have namespaces specified.

17/Jul/2007 14:16 PM

Jan Moser said:

Thanks a lot for this hint! it really saved me hours of debugging!

24/Oct/2007 09:28 AM

Caspar said:

Thanks for sharing! Really, really helpful!

08/Jun/2008 00:55 AM

Arthur said:

It seems I've missed something in this article.

I have one abstract class CategoryAttribute and three classes that inherit from him: IntCategoryAttribute, StringCategoryAttribute and FloatCategoryAttribute.

I've written like in article, but it doesn't work

15/Sep/2008 15:30 PM

Kyle K said:

This article saved me a lot of time that would have been spent banging my head against the desk.

I needed to serialize a generic List of an abstract base class. This did the trick.

Thank you!!

19/Nov/2008 03:25 AM

Normalex said:

Hi Dave,

your advise is really handy and answers my question. However the last comment about factory patterns got me thinking further. Did you manage to find any good example of using factories to deserialize inherited classes from the abstract one?

05/Nov/2009 06:48 AM

Andez said:

Brilliant. Just what I was looking for. Works a treat. Thought I may have to write my own implementation.

Cheers

Andez

11/Feb/2010 15:44 PM

sushant jadhav said:

Thanks Dave.

28/Oct/2010 19:45 PM

Add Comment

Name
Comment
 

Your comment has been received and will be shown once it passes moderation.