反序列化向后兼容性
我试图用旧版本的应用程序反序列化“SomeClass”。 我得到以下exception
System.Runtime.Serialization.SerializationException:ObjectManager发现无效的修正次数。 这通常表示Formatter中存在问题。
当我序列化0.9版并尝试使用0.8版反 序列化时,反序列化会引发exception。 我认为OptionalField
属性可以解决问题,但事实并非如此。
// Version 0.8 [Serializable()] class Foo{ Bar b; } // Version 0.9 [Serializable()] class Foo{ Bar b; [OptionalField] Zoo z; }
鉴于我无法更改版本0.8,我应该如何向Foo对象添加更多状态,以便以前的版本可以反序列化它们的任何内容?
任何指针都会非常感激。
Update 1 Bar和Zoo是其他可序列化的类,包含Hashtables和其他可序列化的东西。 这些课程中的所有内容都是可序列化的。 另外,我没有任何支柱。
首先,永远不要将CLR的序列化function用于任何类似于长期存储的function。 我们通常会犯这样的错误,将对象放在blob数据库字段中并在后面拍拍我们自己很聪明。 然后CLR得到一个补丁或我们的程序集更改版本,你搞砸了。 所以不要这样做。
如果您仍想这样做,管理问题的最佳方法是创建自己的SerializationBinder
,如下所示:
public sealed class CustomBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { Type typeToDeserialize = null; if (typeName.IndexOf("SomeType") != -1) { typeToDeserialize = typeof(Foo.Bar.Bax.NewType); } else if (typeName.IndexOf("SomeOtherType") != -1) { typeToDeserialize = typeof(Foo.Bar.Bax.SomeOtherNewType); } else { // ... etc } return typeToDeserialize; } }
在反序列化之前设置您正在使用的格式化程序的Binder
属性,以便它覆盖默认值。
请注意,我不是在这里提供插件解决方案,我建议如何解决问题。 一旦你转换了你正在做的任何事情,调查其他序列化技术,如protobuf,或编写自己的。 无论哪种方式,您都不应该依赖CLR来获得长期的序列化支持。
如果每个版本的构造函数兼容(例如,两个版本都有无参数或Foo(Bar b)
构造函数),则可以调用
BinaryFormatter formatter = new BinaryFormatter(); formatter.AssemblyFormat = Formatters.FormatterAssemblyStyle.Simple;
在反序列化流之前。
作为一个咨询调查这个问题的人“在为时已晚”…我强烈建议不要通过BinaryFormatter坚持。 对于同步的2个app域之间的瞬态传输是可以的,但这是关于IMO的。 存在其他没有这些问题的序列化工具。 就二进制而言,protobuf-net是一个非常合理的选择 – 允许添加/删除/重命名等没有痛苦。
似乎有一种方法是使用版本化对象,这样您就可以尝试使用最新版本反序列化对象。 如果这不起作用,请退回一个版本,直到它成功。 然后,在获得对象后,将其更新为对象的最新版本,并对没有数据的任何字段使用默认值。
optional field
属性应该已经完成了。 您可以发布您尝试序列化的实际类。
你可以先试试这些东西 –
将structs
转换为classes
如果有的话
尝试Soap Serialization
而不是binary serilization
上述就是C#学习教程:反序列化向后兼容性分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/961037.html