2015-07-20 69 views
1

我正在創建一個vb.net應用程序,它需要能夠反序列化在不同應用程序中序列化的文件以及序列化可以在其他應用程序中反序列化的文件。Type.GetType在SerializationBinder中返回Nothing

我想通過使用SerializationBinder在序列化/反序列化期間轉換類型使這項工作。使用This article from MSDN作爲參考,這是我在這一點....

在我的反序列化功能:

myDeserializer.Binder = New TypeConverter() 
openCount = DirectCast(myDeserializer.Deserialize(stream), Count) 

然後:

Class TypeConverter 

    Inherits SerializationBinder 

    Public Overrides Function BindToType(assemblyName As String, typeName As String) As Type 

     Dim returnType As Type = Nothing 

     If assemblyName = "[name from other application]" Then 
      assemblyName = Assembly.GetExecutingAssembly().FullName 
     End If 

     If typeName = "[other application namespace].Count" Then 
      typeName = "Count" 
     End If 

     returnType = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName)) 

     Return returnType 

    End Function 

End Class 

的如果陳述是真實的,所以assemblyName和typeName正確設置。但是returnType沒有被設置 - 它仍然沒有。我不知道爲什麼。

請注意,我在兩個應用程序中都有相同的類(即Count,這是它們之間序列化/反序列化的類型)。

謝謝!

+0

不是沒有,但你可以通過使用[protobuf網]避免組件之間共享數據的問題(https://www.nuget.org/packages/protobuf-net /)而不是BinaryFormatter。與BF不同,它不會將彙編文化級信息編碼到輸出中 – Plutonix

+1

是'typeName =「Count」'僅用於演示目的嗎?我相信通常它會有一個命名空間限定符。即'typeName =「rootNamespace.Count」' – TnTinMn

+0

@TnTinMn - 「Count」是被序列化/反序列化的對象類型。當您在自己的名稱空間中引用對象類型時,不必在前面指定名稱空間。我改變了「從其他應用程序類型」的文字,這可能有助於更清楚地說明。 – Andarta

回答

0

好的,事實證明,在這種情況下(在此使用中使用Type.GetType),它不起作用,除非在類型之前指定名稱空間。所以我有typeName = "Count"我不得不將其改爲typeName = "[my project].Count"https://msdn.microsoft.com/en-us/library/a87che9d%28v=vs.110%29.aspx

它也證明,這個函數重複進入的每一個類型(不只是具體什麼是反序列化,但對於每種類型的屬性)。因此,因爲我的「Count」類型包含其他自定義類型的屬性,還有一些是其他自定義類型的列表,所以我必須確保每個類型都得到正確轉換。

我現在在這裏:在逐步完成過程中,看起來一切正常。但是,在它轉換了第一個類型爲自定義類型結構的列表之後,在嘗試轉換下一個類型時,我得到一個參數異常。

這是現在的代碼:

Public Overrides Function BindToType(assemblyName As String, typeName As String) As Type 

    If assemblyName.Contains("[other project]") Then 
     assemblyName = Assembly.GetExecutingAssembly().FullName 
    End If 

    If typeName.Contains("System.Collections.Generic.List`1[[[Other Project].[Type],") Then 
      typeName = String.Format("System.Collections.Generic.List`1[[[my project].[type]], {0}", Assembly.GetExecutingAssembly().FullName) 
    ElseIf typeName.Contains("System.Collections.Generic.List`1[[[Other Project].[type]+[structure],") Then 
      typeName = String.Format("System.Collections.Generic.List`1[[[My project].[Type]+[Structure], {0}", Assembly.GetExecutingAssembly().FullName) 
    ElseIf typeName.Contains("[Other Project]") Then 
      typeName = Replace(typeName, "[Other Project]", "[My Project]") 
    End If 

    Return Type.GetType(String.Format("{0}, {1}", typeName, assemblyName)) 

End Function 

所以System.Collections.Generic.List`1 [[[我的項目] [類型] + [結構]是一個自定義的列表類型的結構。它涉及到的第一個似乎轉換很好,但隨後試圖轉換無論是未來的時候,我得到這個:

附加信息: 類型的「System.Runtime.Serialization.TypeLoadExceptionHolder」對象不能被 轉換爲 'System.Collections.Generic.List`1 [My Project.Type + Structure]'。

在這種情況下的類型和結構是以前轉換的類型...不是在拋出此異常時正在轉換的類型。

不知道是怎麼回事....

+0

嗯,我是盲目的......事實證明,問題是我在每個結尾處都缺少了一對括號 例如:更改: 「typeName = String.Format(」System.Collections.Generic.List'1 [[[my project]。[type]],{0}「,Assembly .GetExecutingAssembly()。FullName)「 收件人: 」typeName = String.Format(「System.Collections.Generic.List'1 [[[my project]。[type]],{0}]]」,Assembly .GetExecutingAssembly()。FullName)「 爲什麼我沒有得到一個錯誤,直到它試圖轉換特定的結構列表和之前的所有東西似乎工作,我沒有想法。 – Andarta

相關問題