我正在尝试反序列化使用相同程序集的早期版本(强名称)序列化的对象,因此只有版本号不同(相同的应用程序,相同的程序集,类没有更改)。我使用BinaryFormatter进行序列化/反序列化。 我创建了一个自定义SerializationBinder来处理版本号问题。这适用于简单的类。 现在的问题是,我的类有一个数据集成员,其中包含另一个类的对象。这是反序列化失败的地方。有没有可能,我可以根据这些对象进行反序列化? 我们有很多客户在他们的数据库中有序列化对象,所以应该可以使用更新的版本反序列化它们,而不改变一般的序列化概念。反序列化工作多年,但现在我们不得不更改导致问题的程序集的版本号。
代码太复杂了,无法发布整个内容,我将其缩小为一个简单的示例,在反序列化时抛出相同的异常。
ClassA - 要序列化的类,
ClassB - ClassA.dataset中ClassB的对象
<Serializable()> _
Public Class ClassA
Public ID As Int64
Public data As DataSet
End Class
<Serializable()> _
Public Class ClassB
Public str As String = ""
Public num As Int64
End Class
初始化要序列化的对象和用于序列化和反序列化的方法调用
Imports System
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Imports serialisierung
Public Class Form1
Private Sub btnSerialize_Click(sender As Object, e As EventArgs) Handles btnSerialize.Click
Try
Dim myClassA As ClassA = Nothing
myClassA = New ClassA()
myClassA.data = New DataSet
myClassA.data.Tables.Add("ClassA")
myClassA.data.Tables(0).Columns.Add("ClassB", GetType(ClassB))
Dim myClassB As New ClassB()
myClassB.str = "some String"
myClassB.num = 3
Dim drClassB As DataRow
drClassB = myClassA.data.Tables(0).NewRow
drClassB.Item("ClassB") = myClassB
myClassA.data.Tables(0).Rows.Add(drClassB)
Dim ser As New CSerializer
ser.serialize(myClassA)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub btnDeserialize_Click(sender As Object, e As EventArgs) Handles btnDeserialize.Click
Try
Dim ser As New CSerializer
Dim obj As ClassA = ser.deserialize()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
End Class
序列化类
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Public Class CSerializer
Private filename As String = "C:\bin.txt"
Public Sub serialize(obj As ClassA)
Try
If (File.Exists(filename)) Then
File.Delete(filename)
End If
Dim stream As FileStream = File.Create(filename)
Dim formatter As New BinaryFormatter()
formatter.Serialize(stream, obj)
stream.Close()
Catch ex As Exception
End Try
End Sub
Public Function deserialize() As ClassA
Dim obj As ClassA
Try
Dim stream As FileStream
Dim formatter As New BinaryFormatter()
formatter.Binder = New AllowAllAssemblyVersionsDeserializationBinder()
formatter.AssemblyFormat = Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
stream = File.OpenRead(filename)
obj = formatter.Deserialize(stream)
stream.Close()
Catch ex As Exception
Dim str As String = ex.Message
End Try
Return obj
End Function
End Class
NotInheritable Class AllowAllAssemblyVersionsDeserializationBinder
Inherits System.Runtime.Serialization.SerializationBinder
Public Overrides Function BindToType(ByVal AssemblyName As String, ByVal TypeName As String) As System.Type
Dim myType As Type = GetType(ClassA)
Dim beginTypeName As String
Dim TypeToDeserialize As Type
If TypeName.StartsWith("System.") Then
If TypeName.IndexOf("[") >= 0 Then
beginTypeName = TypeName.Substring(0, TypeName.IndexOf("["))
TypeName = String.Format("{0}[[{1}]]", beginTypeName, myType.AssemblyQualifiedName)
End If
Else
AssemblyName = myType.Assembly.ToString
TypeName = myType.FullName
End If
TypeToDeserialize = Type.GetType(String.Format("{0}, {1}", TypeName, AssemblyName))
Return TypeToDeserialize
End Function
End Class
序列化对象看起来像(在示例中保存为文件,我们的应用程序将序列化对象存储在数据库中。
ÿÿÿÿ Qserialisierung, Version=1.2.3.4, Culture=neutral, PublicKeyToken=e3eee34ac29f76ba NSystem.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 serialisierung.ClassA IDdata System.Data.DataSet System.Data.DataSet DataSet.RemotingVersion XmlSchemaXmlDiffGramSystem.Version ©<?xml version="1.0" encoding="utf-16"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="ClassA">
<xs:complexType>
<xs:sequence>
<xs:element name="ClassB" msdata:DataType="serialisierung.ClassB, serialisierung, Version=1.2.3.4, Culture=neutral, PublicKeyToken=e3eee34ac29f76ba" type="xs:anyType" msdata:targetNamespace="" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema> •<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"><NewDataSet><ClassA diffgr:id="ClassA1" msdata:rowOrder="0" diffgr:hasChanges="inserted"><ClassB xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><str>some String</str><num>3</num></ClassB></ClassA></NewDataSet></diffgr:diffgram> System.Version _Major_Minor_Build _Revision ÿÿÿÿÿÿÿÿ