Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialization and versioning

I need to serialize some data to string. The string is then stored in DB in a special column SerializeData.

I have created special classes that are used for serialization.

[Serializable]
public class SerializableContingentOrder
{
    public Guid SomeGuidData { get; set; }
    public decimal SomeDecimalData { get; set; }
    public MyEnumerationType1 EnumData1 { get; set; }
}

Serialization:

protected override string Serialize()
{
    SerializableContingentOrder sco = new SerializableContingentOrder(this);

    MemoryStream ms = new MemoryStream();
    SoapFormatter sf = new SoapFormatter();
    sf.Serialize(ms, sco);
    string data = Convert.ToBase64String(ms.ToArray());
    ms.Close();
    return data;
}

Deserialization:

protected override bool Deserialize(string data)
{
    MemoryStream ms = new MemoryStream(Convert.FromBase64String(data).ToArray());
    SoapFormatter sf = new SoapFormatter();

    SerializableContingentOrder sco = sf.Deserialize(ms) as SerializableContingentOrder;
    ms.Close();
    return true;
}

Now I want to have versioning support. What happens if I change SerializableContingentOrder class. I want to be able to add new fields in the future.

Do I have to switch to DataContract serialization? Please give me short snippet?

like image 478
Captain Comic Avatar asked Jul 06 '10 10:07

Captain Comic


1 Answers

I strongly advocate against storing BinaryFormatter or SoapFormatter data in the database; it is:

  • brittle
  • not version tolerant
  • not platform independent

BinaryFormatter is OK for data transfer between .NET assemblies (at a push), but I would recommend a more predictable serializer. DataContractSerializer is an option (as is JSON or XmlSerializer), but I would not use NetDataContractSerializer for all the same reasons above. I would be tempted to use protobuf-net, since that is efficient binary in a known efficient format, platform independent and version tolerant!

For example:

[DataContract]
public class SerializableContingentOrder
{
    [DataMember(Order=1)] public Guid SomeGuidData { get; set; }
    [DataMember(Order=2)] public decimal SomeDecimalData { get; set; }
    [DataMember(Order=3)] public MyEnumerationType1 EnumData1 { get; set; }
}

Serialization:

protected override string Serialize()
{
    SerializableContingentOrder sco = new SerializableContingentOrder(this);   
    using(MemoryStream ms = new MemoryStream()) {
        Serializer.Serialize(ms, sco);
        return Convert.ToBase64String(ms.ToArray());
    }
}

Deserialization:

protected override bool Deserialize(string data)
{
    using(MemoryStream ms = new MemoryStream(Convert.FromBase64String(data)) {
        SerializableContingentOrder sco =
               Serializer.Deserialize<SerializableContingentOrder>(ms)
    }
    return true;
}
like image 129
Marc Gravell Avatar answered Sep 28 '22 07:09

Marc Gravell