GeekZilla
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.
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
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.
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.
Jan Moser said:
Thanks a lot for this hint! it really saved me hours of debugging!
Caspar said:
Thanks for sharing! Really, really helpful!
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
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!!
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?
Andez said:
Brilliant. Just what I was looking for. Works a treat. Thought I may have to write my own implementation.
Cheers
Andez
sushant jadhav said:
Thanks Dave.