In a previous question about serialising an object to an XmlDocument in C#, I needed to serialise some fault information to an XmlDocument that was returned from a asmx-style webservice call. On the client I need to de-serialise the XmlDocument back to an object.
This is straightforward enough if you know the type, but I realised I wanted a flexible approach where the type to de-serialise to is also encoded in the XmlDocument. I’m currently doing it manually by adding an XmlNode to the XmlDocument that has the type name, calculated as follows:
Type type = fault.GetType();
string assemblyName = type.Assembly.FullName;
// Strip off the version and culture info
assemblyName = assemblyName.Substring(0, assemblyName.IndexOf(",")).Trim();
string typeName = type.FullName + ", " + assemblyName;
Then on the client I first get this type name back from the XmlDocument, and create the type object that is passed into the XmlSerialiser thus:
object fault;
XmlNode faultNode = e.Detail.FirstChild;
XmlNode faultTypeNode = faultNode.NextSibling;
// The typename of the fault type is the inner xml of the first node
string typeName = faultTypeNode.InnerXml;
Type faultType = Type.GetType(typeName);
// The serialised data for the fault is the second node
using (var stream = new StringReader(faultNode.OuterXml))
{
var serialiser = new XmlSerializer(faultType);
objectThatWasSerialised = serialiser.Deserialize(stream);
}
return (CastToType)fault;
So this is a brute-force approach, and I was wondering if there’s a more elegant solution that somehow includes the typename of the serialised type automatically, rather than manually recording it elsewhere?
I had faced a similar problem and I came up with the same solution. As far as I am concerned, that is the only way to keep types together with values in XML serialization.
I see you are cutting assembly version out as I did too. But I’d like to mention, that you will have troubles with generic types as theirs signature looks like that:
So I made a function to only cut out the assembly version(s), which seems to be enough to get rid of versioning problems: