0

在名为“application1”的应用程序中,我将此结构序列化为二进制:

namespace namespace1
{ 
[System.Serializeable]
class ClassA
   { 
     List<ClassB> List 
   } 
}

在名为“application2”的应用程序中,我必须反序列化这个二进制文件,但我的 ClassA 和 ClassB 必须在 namespace2 而不是 namespace1 内。

所以我写了一个序列化活页夹:

public class TypeNameConverter : SerializationBinder
    {
        public override Type BindToType(string assemblyName, string typeName)
        {
            assemblyName = Assembly.GetExecutingAssembly().FullName;

            if (typeName.Contains("nemespace1."))
                typeName = typeName.Replace("nemespace1.", "nemespace2.");

            Type retType = Type.GetType(string.Format("{0}, {1}", typeName, assemblyName));
            return retType;
        }
    }

我像这样使用它:

 binaryFormatter.Binder = new TypeNameConverter();
 (T)binaryFormatter.Deserialize(memoryStream);

这成功地将 namespace1.ClassA 反序列化为 namespace2.ClassA,但未能进一步将列表 od nemespace1.ClassB 反序列化为 namespace2.ClassB 列表。我猜它失败了,因为 ClassB 的列表被封装到 ClassA 中并且 BindToType() 函数没有被“内部元素”调用,它只为 ClassA 调用一次,然后尝试反序列化 ClassA 并且无法提取 ClassB 列表并出现错误:

 SerializationException: Could not find type
    'System.Collections.Generic.List`1[[namespace1.ClassB, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'.

我不能对 application1 做任何调整(不能改变我做序列化的方式) 我只能调整 application2 中的反序列化逻辑。

我正在尝试为这个特定问题找到解决方案,任何人都有类似的问题,或者可能有关于如何解决这个问题的想法?

谢谢!

4

1 回答 1

1

我发现的问题的唯一解决方案是手动更改已经序列化的二进制文件中的类型。这包括读取包含 namespace1.ClassA 类型的序列化对象的二进制文件,在二进制文件中查找表示定义类型的字符串(即“namespace1.ClassA”)的字节,并将这些字节替换为字符串“namespace2.ClassA”,从而使反序列化器认为序列化对象的类型为 namespace2.ClassA 而不是 namespace1.ClassA,这有效!

指向包含黄金信息的问题的链接、执行此操作所需知道的所有内容以及示例代码。 如何分析二进制序列化流的内容?

于 2018-07-31T09:53:12.607 回答