序列化和版本控制

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

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

[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序列化? 请给我简短的片段?

强烈 反对在数据库存储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(ms) } return true; } 

如果要支持版本控制,可以使用两种方法。 使用DataContracts或使用版本容错序列化。 两者都有效。

DataContacts自动处理字段的添加和删除。 有关详细信息,请参阅数据联系人版本控制和最佳实践:数据合同版本控制 。

DataContact示例

 [DataContract] public class ContingentOrder { [DataMember(Order=1)] public Guid TriggerDealAssetID; [DataMember(Order=2)] public decimal TriggerPrice; [DataMember(Order=3)] public TriggerPriceTypes TriggerPriceType; [DataMember(Order=4)] public PriceTriggeringConditions PriceTriggeringCondition; } 

版本容忍序列化示例

 // Version 1 [Serializable] public class SerializableContingentOrder { public Guid TriggerDealAssetID; public decimal TriggerPrice; public TriggerPriceTypes TriggerPriceType; // Omitted PriceTriggeringCondition as an example } // Version 2 [Serializable] public class SerializableContingentOrder { public Guid TriggerDealAssetID; public decimal TriggerPrice; public TriggerPriceTypes TriggerPriceType; [OptionalField(VersionAdded = 2)] public PriceTriggeringConditions PriceTriggeringCondition; [OnDeserializing] void SetCountryRegionDefault (StreamingContext sc) { PriceTriggeringCondition = /* DEFAULT VALUE */; } } 

有关版本容错序列化的更多信息。 特别要注意页面底部的最佳实践。

注意,DataContracts是在.NET 3.5中引入的,因此如果您需要定位.NET 2.0,则可能没有该选项。

HTH,

从.NET 2.0开始,如果使用BinaryFormatter支持版本容错序列化。 SoapFormatter还支持一些版本容错function,但不支持BinaryFormatter支持的所有function,更具体地说,不支持无关数据容差。

有关更多信息,您应该检查:

版本容忍序列化

最简单的方法是使用OptionalFieldAttribute修饰新字段。 它并不完美,但它可能适用于您的情况。