序列化和版本控制

问题描述 投票:5回答:4

我需要将一些数据序列化为字符串。然后将该字符串存储在DB的特殊列SerializeData中。

我创建了用于序列化的特殊类。

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

序列化:

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;
}

反序列化:

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;
}

现在,我想获得版本支持。如果我更改SerializableContingentOrder类,会发生什么情况。我希望将来能够添加新字段。

我必须切换到DataContract序列化吗?请给我简短的摘要?

c# .net serialization versioning
4个回答
11
投票

强烈主张反对在数据库中存储BinaryFormatterSoapFormatter数据;它是:

  • 脆性
  • 不支持版本
  • 非平台无关

BinaryFormatter可以在.NET程序集之间进行数据传输(按一下),但是我建议使用更可预测的序列化程序。 DataContractSerializer是一个选项(JSONXmlSerializer也是如此),但是出于上述所有相同的原因,我将不会使用NetDataContractSerializer。我将]倾向于使用protobuf-net,因为它是一种有效的二进制文件,具有已知的有效格式,独立于平台且具有版本兼容性!

例如:

[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; }
}

序列化:

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

反序列化:

protected override bool Deserialize(string data)
{
    using(MemoryStream ms = new MemoryStream(Convert.FromBase64String(data)) {
        SerializableContingentOrder sco =
               Serializer.Deserialize<SerializableContingentOrder>(ms)
    }
    return true;
}

7
投票

如果要支持版本控制,您有两个选择。使用DataContracts或使用版本允许序列化。两者都有效。


3
投票

。NET 2.0起,如果您使用BinaryFormatter,则具有版本兼容序列化支持。 SoapFormatter还支持某些版本公差功能,但不支持BinaryFormatter支持的所有功能,更具体地说,不支持无关的数据公差。


2
投票

最简单的方法是用OptionalFieldAttribute装饰新字段。它不是完美的,但可能会针对您的情况。

© www.soinside.com 2019 - 2024. All rights reserved.