我在写this CodeProject article 时第一手发现了这些序列化问题(滚动到“从磁盘加载目录”,大约一半)。
基本上,我正在使用 ASP.NET 应用程序序列化某些内容 - 重新启动 IIS 应用程序后无法读取序列化数据(由于 ASP.NET 所做的整个动态编译/临时程序集缓存/等)!哎哟!
无论如何,我的第一点是反序列化过程中抛出的异常包含强名称
找不到程序集 h4octhiw,Version=0.0.0.0,Culture=neutral,PublicKeyToken=null
显然你是正确的,你想要的信息在“某处”。理论上(是的,这是一个可怕的想法)您可以捕获序列化异常并解析旧版本详细信息的错误(当然“当前”反序列化将在不抛出的情况下工作)......但也可能有更好的方法...... .
第二点与我实施的解决方案有关(使用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 可能是您应该调查“使用”它的方法。
仅供参考,上面的代码是这样“连接”的:
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);