【问题标题】:Assembly Independent Serialization in .NET.NET 中的程序集独立序列化
【发布时间】:2011-11-01 12:20:42
【问题描述】:

我使用序列化/反序列化技术。 BinaryFormatter 类。 每次创建新程序集时,即使类结构相同,BinaryFormatter 也无法反序列化二进制数据,但程序集版本不同。 如果类结构保持不变,是否可以在不检查程序集版本的情况下反序列化二进制缓冲区?

【问题讨论】:

  • 你能把要反序列化的类移动到一个单独的程序集中吗?显然它没有改变?
  • 是的,我可以。我正在寻找一种方法来跳过程序集版本检查,并自行承担风险。

标签: c# deserialization binaryformatter


【解决方案1】:

试试这个:

public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        return Type.GetType(String.Format("{0}, {1}", typeName, Assembly.GetExecutingAssembly().FullName));
    }
}
formatter.Binder = new CurrentAssemblyDeserializationBinder();
formatter.Deserialize(inStream);

已添加主题海报:

是的,它有效。只需确保二进制数据中是否存在任何类型的 System.Generic 或其他 Lib,那么您必须不加更改地传递它们。 “ResizableControls” - 旧的程序集库名称,“EntityLib” - 新的程序集名称。 此外,版本号也将按需更换。

public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        string name;
        if (assemblyName.Contains("ResizableControl"))
        {
            name = Assembly.GetAssembly(typeof(EntityLib.Pattern)).ToString();
        }
        else
        {
            name = assemblyName;
        }
        return Type.GetType(String.Format("{0}, {1}",
            typeName.Replace("ResizableControl", "EntityLib"), name));
    }
}

谢谢,正是我需要的。

【讨论】:

  • 它是否使反序列化程序集独立?
  • @Kirk Robb 二进制格式化程序将类型信息存储在序列化对象中,以便它知道将其反序列化为什么类型。通过从 SerializationBinder 类继承,可以将所有类型的请求从二进制格式化程序重定向到当前程序集中包含的类型。让我知道它是否有效。
  • 也许使用另一种序列化技术会更好,就像 Marc Gravell 所说的那样。然而,你只是用这个救了我的命。我在二进制套接字连接中使用它,这对 BinaryFormatter 非常有用。谢谢!
【解决方案2】:

这是BinaryFormatter 所固有的。 你可以做一些高级的事情来解决它(使用代理等),但这并不容易,老实说我不推荐它。

强烈建议您查看基于合约的序列化程序;例如:

  • XmlSerializer
  • DataContractSerializer(但不是NetDataContractSerializer
  • protobuf-net

(我偏向于最后一个,因为它提供了更高效的输出,并且故意避免了一些更多版本问题)

在所有这些情况下,数据存储(至少在默认设置下)不包括任何类型的知识,除了名称暗示的合同,或指定的合同(通常在属性中)。

【讨论】:

  • @Tigran 我可以整天谈论那个;p
  • 我只能做一个 +1 :P 但认真看看它,因为我以前需要一些序列化...谢谢!
  • +1 用于 protobuf-net。本地 CLR 序列化类型的任何长期存储都是一场灾难。
  • Marc,你推荐哪个版本的 Protobuf?
  • @Kirk 我会推荐 protobuf-net,但那是因为我花了很多空闲时间来编写它;p 这实际上是我们在 stackoverflow 上使用的,例如
【解决方案3】:

我认为这是 BinaryFormatter 的一个已知问题 - here 是一个可能的解决方案 您可以使用 SerializationBinder 控制要加载的类型 - 该链接提供了代码和如何使用它的示例(在几乎所有 .net 语言中)

【讨论】:

  • 感谢您的回复。这很酷。有一个“但是”——就我而言,类结构相同,程序集不同,甚至程序集的版本相同,但 BinaryFormatter 检查所有细节,例如文件创建日期。它使反序列化不可撤销。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-21
  • 1970-01-01
  • 2016-06-05
  • 2012-05-27
  • 1970-01-01
相关资源
最近更新 更多