带有List <T>的SerializationBinder

dan*_*dan 10 .net c# serialization binaryformatter

我正在努力使BinaryFormatter我的装配的不同版本的工作.我希望反序列化的实际类在每个程序集版本中完全相同,但在反序列化时,因为序列化对象包括它们来自的程序集名称,所以BinaryFormatter抱怨它无法找到正确的程序集.所以我创建了一个自定义SerializationBinder,告诉它BinaryFormatter始终反序列化到当前的程序集版本.

我的方案工作正常,可以反序列化对象,但如果我的对象是一个T列表,它不起作用,其中T是从我的程序集的旧版本序列化的类型.

是否有一些方法可以使用Lists和其他泛型类型,其中type参数是我的程序集中的类?

//the object i want to deserialize
class MyObject
{
     public string Name{get;set;}
}

//my binder class
class MyBinder : SerializationBinder
{
    static string assemblyToUse = typeof (MyObject).Assembly.FullName;
    public override Type BindToType(string assemblyName, string typeName)
    {
        var isMyAssembly = assemblyName.StartsWith("oldAssemblyName");
        var assemblyNameToUse = isMyAssembly ? assemblyToUse : assemblyName;
        var tn = typeName + ", " + assemblyNameToUse;
        return Type.GetType(tn);            
    }
}


//my deserialize method
static object BinaryDeserialize(string input)
{
    var arr = Convert.FromBase64String(input);
    var ms = new MemoryStream(arr);
    ms.Seek(0, SeekOrigin.Begin);
    var bf = new BinaryFormatter();
    bf.Binder = new MyBinder();
    var obj = bf.Deserialize(ms);

    return obj;
}

static void Test()
{
    //this works
    //serialized(new MyObject());
    var str = ReadSerialized_MyObject();  
    var obj = BinaryDeserialize(str);

    //this doesn't work
    //serialized(new List<MyObject>());
    var str2 = ReadSerialized_List_of_MyObject(); 
    var obj = BinaryDeserialize(str2);
}
Run Code Online (Sandbox Code Playgroud)

小智 7

如果从版本1.0.0.0程序集序列化List <MyClass>的实例,将要求SerializationBinder.BindToType函数提供此类型:

System.Collections.Generic.List`1[[MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=12345678901234567890]]
Run Code Online (Sandbox Code Playgroud)

要将List <MyClass>类型重新映射到版本2.0.0.0程序集,您需要将类型名称更改为:

System.Collections.Generic.List`1[[MyAssembly.MyClass, MyAssembly]]
Run Code Online (Sandbox Code Playgroud)

需要注意的要点是,程序集名称不是完全限定的.如果您尝试使用2.0.0.0版本号完全限定程序集名称,则它将不起作用.