8

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

4

3 回答 3

8

试试这个:

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));
    }
}

谢谢,这正是我需要的。

于 2011-08-22T23:07:53.940 回答
6

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

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

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

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

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

于 2011-08-22T21:57:09.890 回答
1

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

于 2011-08-22T21:53:33.477 回答