views:

34

answers:

1

I have a few classes to serialize, and deserialize, those classes implement an interface and thats all I really know at runtime about them.

The serialized xml is stored in a database and then, at some point I will need to deserialize this xml into a valid type.

I was thinking of using XmlSerializer , but the constructor requires that I know the type of the data to deserailize. I have this info available when serializing, however, not there when deserializing

So far I can think of a few options, but tbh they dont seem optimal, there must be a better way?

  1. Store the type, as well as the xml. Do Type.GetType(AssemblyQualifiedName_xmlType)
  2. Store the type within the xml. Use a base class that contains the type, this is a solution that I particularly dont like because is very invasive.
  3. try to use this constructor, http://msdn.microsoft.com/en-us/library/7dhb8wb8.aspx I havent tried this. and I want to know for a fact that I wont resolve to a similar but not the same object that it was serialized from.

I would think this is a solved problem and I m just not seeing an obvious solution. What s the best practice in this scenario?.

Note: I have tried serializing to binary, and that works perfectly, but the requirements of the system are that the classes are stored as xml.

Thanks

A: 

Frankly, XmlSerializer is not the best-designed component of the .NET framework… What I do in these situations is using a serialization-surrogate class that implements IXmlSerializable and performs transparent (de)serialization of the actual payload.

The following standard XML attribute can be leveraged:

  • xsi:type to hold the type indication;
  • xsi:nil to indicate an empty (null) payload.

The serialization method needs to inspect the payload, output the xsi:type attribute and serialize the data. This can be achieved by using a XmlSerializer instance for the actual payload-data-type.

The deserialization method inspects the attributes and deserializes the payload accordingly. You can deserialize simple type by using a combination of XmlConvert.ToXyz(reader.ReadContentAsString()), where Xyz is the actual primitive type (e.g. Int64).

Note that in case your XML has to follow a particular schema, you'll most likely end up doing the (de)serialization manually and/or first inferring the data type from the XML, and then using a XmlSerializer instance with the correct type. It's a bit cumbersome process to get the XmlSerializer up-and-running as it's quite limited.

Ondrej Tucny
@downvoter Would like to know what's particularly wrong about my answer. I'm ready to clarify or explain anything :-)
Ondrej Tucny