如何反序列化已更改类型的旧数据?
我有使用二进制序列化存储以下类的数据:
[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; }
}
...
}
这导致反序列化旧数据时出现问题。
我的第一个想法是实现 ISerialized,但是这个类有许多属性以及数百个继承类,我也必须实现它。
我想在反序列化期间更改旧数据以匹配当前结构,或者有一种干净的方法来升级旧数据。
I have data that has been stored using binary serialization for the following class:
[Serializable]
public abstract class BaseBusinessObject
{
private NameValueCollection _fieldErrors = new NameValueCollection();
protected virtual NameValueCollection FieldErrors
{
get { return _fieldErrors; }
set { _fieldErrors = value; }
}
...
}
At some point, the class was changed to this:
[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; }
}
...
}
This is causing issues deserializing old data.
My first thought was to implement ISerializable
, but this class has numerous properties as well as hundreds of inheriting classes that I would have to implement this for as well.
I would like to either change the old data to match the current structure during deserialization or have a clean way of upgrading the old data.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果数据仅在内部使用,我的第一个想法是编写一些简单的一次性代码来使用旧的“NameValueCollection”反序列化二进制数据,将其映射到字典并重新序列化它。 即使处理所有数据需要几天时间,但在新代码上实施补丁来支持旧数据似乎并不值得。
即使它不仅在内部使用,进口商似乎也是最简单的方法。
If the data is only used internally, my first thought would be to write some simple throw-away code to de-serialize your binary data using the old "NameValueCollection", map it to a Dictionnary and re-serialize it. Even if it'll take a few days to process all the data, it doesn't seem worth it to implement a patch on your new code to support the old data.
Even if it's not only used internally, an importer seems like the simplest way to go.
除了 OlivierD 的好建议之外,我建议您定义这两个类,但首先尝试反序列化为当前版本。 在您的 catch 块中,将其反序列化为旧版本,然后将其升级到当前版本并将其保存回来。 当旧版本的实例不存在时,您可以删除代码。
Adding to OlivierD's good advice, I'd suggest you define both classes but initially try to deserialize as the current version. In your catch block, deserialize it as the legacy version, then upgrade it to the current one and save it back. When no instances of the legacy version exist, you can remove the code.
在研究了几个选项后,我得出以下结论:
理想情况下,我能够从原始
NameValueCollection
访问值,并将其手动转换为Dictionary
。 做到这一点的唯一方法是实现 ISerialized,但这带来了两个主要问题:匹配遗留数据的命名以及包含所有继承类的序列化逻辑(其中有数百)。实际上,这让我陷入了困境。 幸运的是,我能够确定该字段实际上仅用作表单验证错误的摘要,并且不应该首先被序列化,因此我已将其从序列化中排除。
After investigating a few options, I made the following conclusions:
Ideally I would be able to access the value from the original
NameValueCollection
and manually convert it toDictionary<string, string>
. The only way to do this would be to implementISerializable
, but this posed two major issues: matching up to the naming of the legacy data and the inclusion of serialization logic for all inheriting classes (of which there are hundreds).Effectively, this put me in a bind. Fortunately, I was able to determine that this field is really only used as a summary of form validation errors and shouldn't be getting serialized in the first place, therefore I have excluded it from serialization.
在不同的名称下添加新的 _
fieldErrors
,例如_fieldErrors2
,并将其设为[可选]
。 然后实现[OnDeserialized]
将数据从_fieldErrors
复制到_fieldErrors2
(如果存在)并清除 _fieldErrors 的方法。Add the new _
fieldErrors
under a different name, say_fieldErrors2
, and make it[Optional]
. Then implement an[OnDeserialized]
Method that copies the data from_fieldErrors
to_fieldErrors2
(if present), and clears _fieldErrors.