当前位置: 动力学知识库 > 问答 > 编程问答 >

.net - Object changed while deserialization

问题描述:

I'm serializing an object and storing the serialized value in db and getting the deserialization to work fine as well after getting values from db.

But problem occurs if the existing object is modified and a new property is added in the class. Then while deserializing it looks for that property in serialized text and upon not finding it there, I get the following error

System.Runtime.Serialization.SerializationException: Member 'temp' was not found.

Is there any way I can know if new property was not there while serialization and can skip that? I'm using custom serialization.

网友答案:

This is a common problem when de/re hydrating instances and changing the underlying type at the same time.

What you can do in these kind of situations is to write the equivalent of a header out along with the property information which can be used upon deserialization so that you can know which fields were actually serialized in the first place. The way that you 'tag' each field is entirely up to you, here I'm going to do it the most naive way just for demonstration purposes:

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");
  }
}

As the code suggests, when you roll-out this change, you should have a good knowledge of what the current mimum level of detail you can expect from the object data in your data stores, so you can still deserialize all the stuff that doesn't perform this.

You could take this a lot further and use strings to track the data that's present, making each string equal to the name of the field that is stored, and then employ some reflection-based solution that will automatically fill the fields. That's likely to be ugly code though (or, at least, I don't have enough time right now to provide an example!).

网友答案:

try XmlSerializer. it is version tolerant.

分享给朋友:
您可能感兴趣的文章:
随机阅读: