Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# serialized object versions

I have the following situation. In my C# application, I have a class which i serialize using XmlSerializer. The class is pretty complex, and an object of my class gets saved on local disc as an application file, which can be opened later (classic save work and reopen work). My problems is that during the development, the class of the object which gets serialized might change. I would like to have a version system, which allows my app to realize that the saved xml it belongs to an older version but still can be opened. Old app versions can not open new xml versions as well.

For example:

class ComplexObject
{
   public string settings1;
   public string settings2;
}

I serialize object, send app in production. Tomorrow my class became

class ComplexObject
{
   public string settings1;
   public string settings2;
   public string settings3;
}

How will my new version of app open serialized objects of old class definitions as well as new class definition with no error on loading file to object (deserialization)

Any suggestions and basic samples are welcomed!

Thanks

like image 509
Iftemi Alin Avatar asked Aug 01 '12 09:08

Iftemi Alin


3 Answers

It all depends on the choice of serializer. In the case of XmlSerializer this is fine and will just work; clients with the new value will load the new value; clients without will not. Sample:

var reader = XmlReader.Create(new StringReader(
    @"<ComplexObject><foo>123</foo><bar>abc</bar></ComplexObject>"));
var ser = new XmlSerializer(typeof (ComplexObject));
var obj = (ComplexObject)ser.Deserialize(reader);

with:

public class ComplexObject
{
    public string foo;
}

which works and loads foo but not bar.

Do not use BinaryFormatter for this - that leads to a world of hurt. If you want binary output, consider something like protobuf-net which is designed to be overtly accommodating with versioning.

like image 64
Marc Gravell Avatar answered Sep 23 '22 05:09

Marc Gravell


Version-tolerant serialization

In short, you either mark fields as Optional (and fill them with default values) or implement deserialization constructor which will parse values as you want them.

like image 45
Serg Rogovtsev Avatar answered Sep 23 '22 05:09

Serg Rogovtsev


I hope I understood your problem correctly. You're having a class serialized to a file. Then you change the class in memory (e.g you add another property). No you want to deserialize this class from the file. This is no problem as long as you only add new properties. They will be ignored by the deserializer. He creates a new instance of your class (that is the reason, why serializable classes have to have a default constructor) and tries to fill the properties he finds in the stream to derserialize. If you change property's type or remove a property, you won't be able to deserialize that.

One workaround for "remove properties" maybe to keep properties you intentionally wanted to remove and ignore those furthermore.

You can take a look at Version Tolerant Serialization explained in msdn http://msdn.microsoft.com/en-us/library/ms229752%28v=vs.80%29.aspx

like image 41
Vinoth Avatar answered Sep 24 '22 05:09

Vinoth