根据这个问题,我有一个要序列化的对象BinaryFormatter
。由于各种原因,我们实现了一个像这样的穷人版本处理,在底部有一个 try-catch 块,用于新版本中但旧版本中没有的字段:
private void readData(FileStream fs, SymmetricAlgorithm dataKey)
{
CryptoStream cs = null;
try
{
cs = new CryptoStream(fs, dataKey.CreateDecryptor(),
CryptoStreamMode.Read);
BinaryFormatter bf = new BinaryFormatter();
string string1 = (string)bf.Deserialize(cs);
// do stuff with string1
bool bool1 = (bool)bf.Deserialize(cs);
// do stuff with bool1
ushort ushort1 = (ushort)bf.Deserialize(cs);
// do stuff with ushort1
// etc. etc. ...
// this field was added later, so it may not be present
// in the serialized binary data. Check for it, and if
// it's not there, do some default behavior
NewStuffIncludedRecently newStuff = null;
try
{
newStuff = (NewStuffIncludedRecently)bf.Deserialize(cs);
}
catch
{
newStuff = null;
}
_newStuff = newStuff != null ?
new NewStuffIncludedRecently(newStuff) :
new NewStuffIncludedRecently();
}
catch (Exception e)
{
// ...
}
finally
{
// ...
}
}
我逐步浏览了我机器上的代码,这似乎有效。当我读取一个旧的序列化对象时,最里面的 try-catch 会按照我的要求处理丢失的部分。
当我去同事的机器上尝试读取对象的旧版本时,顶部的第一个 Deserialize() 调用会引发 SerializationException:
二进制流“220”不包含有效的 BinaryHeader。可能的原因是无效的流或序列化和反序列化之间的对象版本更改。
因此我的问题是:是什么导致对象的版本发生变化?当我在对象的两个版本之间(注释/取消注释新字段)在我的盒子上来回移动时,没有问题,但是在另一个人的盒子上,第一个 Deserialize() 炸弹。我什至不确定从哪里开始寻找,尽管我确实尝试使版本检查更宽松,如下所示:
bf.AssemblyFormat =
System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;