BinaryFormatter反序列化给出了SerializationException

Toa*_*oad 13 .net serialization exception binaryformatter

我得到了:

System.Runtime.Serialization.SerializationException:无法找到程序集'myNameSpace,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null

当试图反序列化另一个程序中的某些数据而不是我用它序列化的程序时.

经过一些谷歌搜索,我发现显然这只能使用共享程序集完成.

但是,我的数据库已满了这个序列化对象,我需要一个实用程序来解决它们.有没有办法覆盖这种行为,只是提供完全相同的类,并强制它反序列化?


我已经找到了这个片段,但我不明白应该如何以及在哪里放置/使用它.

   static constructor() {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
   }

    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
        Assembly ayResult = null;
        string sShortAssemblyName = args.Name.Split(',')[0];
         Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
         foreach (Assembly ayAssembly in ayAssemblies) {
            if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0]) {
                 ayResult = ayAssembly;
                 break;
            }
         }
         return ayResult;
    }
Run Code Online (Sandbox Code Playgroud)

JTt*_*eek 13

如果你知道对象,你可以解决这个问题而不需要DLL ...

http://spazzarama.com/2009/06/25/binary-deserialize-unable-to-find-assembly/

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder(VS.71).aspx

使用"System.Runtime.Serialization.SerializationBinder"类.通过继承此类,可以将所有类型请求从二进制格式化程序重定向到您选择的类型.

下面是一个示例,它允许在当前程序集中找到类型,而不管最初创建序列化流的程序集版本如何:

sealed class AllowAllAssemblyVersionsDeserializationBinder : System.Runtime.Serialization.SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {     
        String currentAssembly = Assembly.GetExecutingAssembly().FullName;

        // In this case we are always using the current assembly
        assemblyName = currentAssembly;

        // Get the type using the typeName and assemblyName
        Type typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
            typeName, assemblyName));

        return typeToDeserialize;
    }
}

public static MyRequestObject Deserialize(byte[] b)
{
    MyRequestObject mro = null;
    var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    using (var ms = new System.IO.MemoryStream(b))
    {
       // To prevent errors serializing between version number differences (e.g. Version 1 serializes, and Version 2 deserializes)
       formatter.Binder = new AllowAllAssemblyVersionsDeserializationBinder();

       // Allow the exceptions to bubble up
       // System.ArgumentNullException
       // System.Runtime.Serialization.SerializationException
       // System.Security.SecurityException
       mro = (MyRequestObject)formatter.Deserialize(ms);
       ms.Close();
       return mro;
    }
}
Run Code Online (Sandbox Code Playgroud)


Eri*_* J. 6

您需要以某种方式提供对原始类型的引用,以便实用程序知道如何反序列化它.

简单的方法是添加最初定义的类型的DLL作为对实用程序项目的引用.

您发布的代码允许您在反序列化程序确定无法找到类型时动态加载相同的DLL.这是一个比较困难的方法(但不是困难),但在这两种情况下,你将需要通过将基准定义的类型......所以可能比较容易只是静态链接的DLL.

如果您的类型当前不在DLL中(例如,如果它们在EXE中),我建议您将EXE中的类从新的DLL中拉出来,并从原始项目和util项目中引用该DLL.