我在编写this CodeProject article时发现了这些序列化问题(滚动到“从磁盘加载目录”,大约过了一半)。
基本上我是用ASP.NET应用程序序列化一些东西 - 并且在重新启动IIS应用程序后(由于ASP.NET所做的整个动态编译/临时程序集缓存等),序列化数据无法读取!哎哟!
不管怎样,我的第一点是反序列化期间抛出的异常包括强名称
找不到装配h4octhiw,版本= 0.0.0.0,文化=中立,公钥=空
很显然你是正确的,你想要的信息是在那里“某处”。理论上(是的,这是一个可怕的想法),你可以捕获序列化异常并解析旧版本细节的错误(当然,'当前'反序列化不会抛出)......但也可能有更好的方法..
第二点涉及我实施的解决方案(使用this info)。我写了一个自定义System.Runtime.Serialization.SerializationBinder
:下面显示的代码是一个例子。
public class CatalogBinder: System.Runtime.Serialization.SerializationBinder
{
public override Type BindToType (string assemblyName, string typeName)
{
// get the 'fully qualified (ie inc namespace) type name' into an array
string[] typeInfo = typeName.Split('.');
// because the last item is the class name, which we're going to
// 'look for' in *this* namespace/assembly
string className=typeInfo[typeInfo.Length -1];
if (className.Equals("Catalog"))
{
return typeof (Catalog);
}
else if (className.Equals("Word"))
{
return typeof (Word);
}
if (className.Equals("File"))
{
return typeof (File);
}
else
{ // pass back exactly what was passed in!
return Type.GetType(string.Format("{0}, {1}", typeName,
assemblyName));
}
}
}
基本上BindToType
报错由反序列化过程为“替代”的最初用于序列化该对象的一个已知类型的机会。我只使用typeName
,但assemblyName
可能包含您之后的信息,并且自定义SerializationBinder可能是您应该调查以“使用”它的方法。
FYI,代码上面 '有线了' 是这样的:
System.Runtime.Serialization.IFormatter formatter =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
formatter.Binder = new CatalogBinder(); // THIS IS THE IMPORTANT BIT
object deserializedObject = formatter.Deserialize(stream);
相关(但不相同):http://stackoverflow.com/questions/929985#930135 - 总之,我不不认为BinaryFormatter“版本”(好)在版本之间...有更好的选择。 – 2009-06-04 14:47:50
或http://stackoverflow.com/questions/881766#881898(再次 - 这只是相关的 - 不是一个复制等) – 2009-06-04 14:50:01