【问题标题】:Binary Deserialization with different assembly version不同程序集版本的二进制反序列化
【发布时间】:2010-10-05 01:43:44
【问题描述】:

我有一个项目,它使用 BinaryFormatter 序列化具有字符串和布尔的结构集合?数据类型。

序列化/反序列化工作正常,但是如果我要更改完成工作的程序集,它无法反序列化,因为二进制文件中的标头表明它需要 Assembly x 而不是 Assembly y 来处理数据.

是否可以将序列化/反序列化设置为与程序集无关?

【问题讨论】:

  • 我遇到了同样的问题...很高兴知道它已得到解决。

标签: .net serialization binaryformatter assemblyversions


【解决方案1】:

您可以通过将自定义 SerializationBinder 分配给格式化程序来控制二进制格式化程序如何解析其类型。这样一来,您就不需要弄乱 AppDomain 的解析事件,并且消除了由此产生的意外副作用的风险。

MSDN有详细示例。

【讨论】:

  • 谢谢,这似乎是最安全的选择 - 特别是如果我将代码移动到不同的程序集中...
  • @mmr:我刚刚对其进行了测试并使其正常工作。从答案中的 MSDN 示例开始,并修改序列化绑定器以允许某些程序集版本不匹配。
  • 您需要注意的一件事是,如果您有嵌套类型(例如自定义对象的自定义集合),您将需要加载多个程序集...尝试逐步执行重载 BindToType 方法。
  • 换个方式怎么样?当您想控制二进制文件中的程序集时如何进行序列化?
【解决方案2】:

您可以更改 BinaryFormatter 属性 AssemblyFormat 以使序列化独立于程序集版本。

// Example
var binFormat = new BinaryFormatter();
binFormat.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;

【讨论】:

  • 它可以工作,但数据应该使用相同的方法进行序列化和反序列化。
【解决方案3】:

挂钩 AppDomain.OnAssemblyResolve 事件并修复程序集名称

private System.Reflection.Assembly OnAssemblyResolve( System.Object sender, System.ResolveEventArgs reArgs )
{
     foreach( System.Reflection.Assembly assembly in System.AppDomain.CurrentDomain.GetAssemblies() ) 
     {
         System.Reflection.AssemblyName assemblyName = assembly.GetName();
         if( assemblyName.FullName == reArgs.Name ) 
         {
              return( assembly );
         }
     }
}

来源:http://osdir.com/ml/windows.devel.dotnet.clr/2003-12/msg00441.html

【讨论】:

  • 我原本打算使用它,但是我可以看到并发执行时可能出现严重失败的极端情况..
【解决方案4】:

存在不依赖于程序集的替代(二进制)序列化引擎 (like this)。

【讨论】:

    【解决方案5】:

    GAC 是您的第一个资源,它允许不同版本的程序集并行共存。但这并不能真正解决任何问题,除非您的应用程序也具有版本容错性。二进制序列化有几个特性来处理版本兼容的序列化。在这个 MSDN library article 中阅读它。

    【讨论】:

    • 感谢 GAC 的建议,但是我尽量不给应用程序留下沉重的足迹,让一切都从自己的文件夹中运行。
    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    相关资源
    最近更新 更多