我正在序列化一个对象并将序列化值存储在db中,并且在从db获取值之后也可以使反序列化正常工作。
但是如果修改现有对象并在类中添加新属性,则会出现问题。然后在反序列化时,它会在序列化文本中查找该属性,如果没有在那里找到它,我会收到以下错误
System.Runtime.Serialization.SerializationException:找不到成员'temp'。
有什么方法我可以知道序列化时是否有新属性,可以跳过吗?我正在使用自定义序列化。
答案 0 :(得分:1)
尝试XmlSerializer
。它是版本容忍的。
答案 1 :(得分:1)
在对实例进行水化并同时更改基础类型时,这是一个常见问题。
在这种情况下你可以做的是写出一个标题的等价物以及可以在反序列化时使用的属性信息,这样你就可以知道哪些字段实际上是先序列化的。你标记'每个字段的方式完全取决于你,在这里,我将以最简单的方式进行演示:
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("_Fields", 2);
info.AddValue("FieldA", FieldA);
info.AddValue("FieldB", FieldB);
}
protected MyObject(SerializationInfo info, StreamingContext context)
{
int fields = 0;
try{
fields = info.GetInt32("_Fields");
}
catch(Exception)
{
/* min known version kicks in instead, i.e.
before you added this field-tracking value */
}
if(fields!=0)
{
//if using an integer tracking field, you could also consider using
//bit flags - changing these tests to (fields & [fieldFlag]) == [fieldFlag]
//which would allow you to accommodate multiple combinations of fields more easily.
if(fields == 1)
FieldA = info.GetInt32("FieldA");
if(fields == 2)
FieldB = info.GetInt32("FieldB");
}
}
正如代码建议的那样,当您推出此更改时,您应该非常了解数据存储中对象数据可以预期的最新细节级别,因此您仍然可以反序列化所有内容这不会执行此操作。
你可以更进一步,并使用字符串来跟踪存在的数据,使每个字符串等于存储的字段的名称,然后使用一些基于反射的解决方案,将自动填充字段。这可能是丑陋的代码(或者,至少,我现在没有足够的时间提供一个例子!)。