序列化和版本控制
我需要将一些数据序列化为字符串。 然后将该字符串存储在特殊列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序列化? 请给我简短的片段?
我强烈 反对在数据库中存储BinaryFormatter
或SoapFormatter
数据; 它是:
- 脆
- 不容忍版本
- 不是平台独立的
BinaryFormatter
适用于.NET程序集之间的数据传输(推送),但我建议使用更可预测的序列化程序。 DataContractSerializer
是一个选项(和JSON
或XmlSerializer
),但我不会因为上述相同的原因而使用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
修饰新字段。 它并不完美,但它可能适用于您的情况。