我有使用二进制序列化存储的数据用于以下类:
[Serializable]
public abstract class BaseBusinessObject
{
private NameValueCollection _fieldErrors = new NameValueCollection();
protected virtual NameValueCollection FieldErrors
{
get { return _fieldErrors; }
set { _fieldErrors = value; }
}
...
}
在某些时候,课程改为:
[Serializable]
public abstract class BaseBusinessObject
{
private Dictionary<string, string> _fieldErrors = new Dictionary<string, string>();
protected virtual Dictionary<string, string> FieldErrors
{
get { return _fieldErrors; }
set { _fieldErrors = value; }
}
...
}
这导致了对旧数据进行反序列化的问题。
我的第一个想法是实现ISerializable
,但是这个类有很多属性以及数百个继承类,我也必须实现它。
我想在反序列化过程中更改旧数据以匹配当前结构,或者使用干净的方法升级旧数据。
答案 0 :(得分:4)
使用其他名称添加新的fieldErrors
,例如_fieldErrors2
,并将其设为[Optional]
。然后实现[OnDeserialized]
方法,将数据从_fieldErrors
复制到_fieldErrors2
(如果存在),并清除_fieldErrors。
答案 1 :(得分:3)
如果数据仅在内部使用,我首先想到的是编写一些简单的丢弃代码,使用旧的“NameValueCollection”对二进制数据进行反序列化,将其映射到Dictionnary并重新序列化。即使处理所有数据需要几天时间,但在新代码上实现补丁以支持旧数据似乎也不值得。
即使它不仅在内部使用,导入器似乎也是最简单的方法。
答案 2 :(得分:2)
添加OlivierD的好建议,我建议您定义这两个类,但最初尝试反序列化为当前版本。在catch块中,将其反序列化为旧版本,然后将其升级到当前版本并保存回来。如果不存在旧版本的实例,则可以删除代码。
答案 3 :(得分:0)
在研究了几个选项之后,我做出了以下结论:
理想情况下,我可以访问原始NameValueCollection
中的值并手动将其转换为Dictionary<string, string>
。实现此目的的唯一方法是实现ISerializable
,但这提出了两个主要问题:匹配遗留数据的命名和包含所有继承类(其中有数百个)的序列化逻辑。
实际上,这让我陷入困境。幸运的是,我能够确定该字段实际上仅用作表单验证错误的摘要,并且不应该首先进行序列化,因此我将其排除在序列化之外。