Dot-Net

BinaryFormatter 反序列化給出 SerializationException

  • December 3, 2015

我得到一個:

System.Runtime.Serialization.SerializationException:找不到程序集’myNameSpace,版本 = 1.0.0.0,文化 = 中性,PublicKeyToken = null

當試圖反序列化另一個程序中的某些數據而不是我序列化它的程序時。

經過一番Google搜尋後,我發現顯然這只能使用共享程序集來完成。

但是,我的數據庫中充滿了這個序列化的對象,我需要一個實用程序來將它們取出。有沒有辦法覆蓋這種行為,只是給它提供完全相同的類並強制它反序列化?


我已經找到了這個片段,但我不明白我應該如何以及在哪裡放置/使用它。

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

您需要以某種方式提供對原始類型的引用,以便實用程序知道如何反序列化它。

最簡單的方法是添加最初定義類型的 DLL 作為對實用程序項目的引用。

您發布的程式碼允許您在反序列化器確定它找不到類型時動態載入相同的 DLL。這是一種更困難的方法(但不是那麼困難),但在這兩種情況下,您都需要一個定義類型的 DLL ……所以通過添加引用來靜態連結可能最簡單。

如果您的類型目前不在 DLL 中(例如,如果它們在 EXE 中),我建議您將類從 EXE 中拉出到新的 DLL 中,並從原始項目和 util 項目中引用該 DLL。

如果您知道對象,則無需 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;
   }
}

引用自:https://stackoverflow.com/questions/2120055