Hallo liebes Forum,
ich wette dieses Problem ist bekannt. Ich konnte in der Suche leider nichts finden. Evtl. einfach die falschen Suchbegriffe. Lasse mich gerne auf einen Thread verweisen.
Zum Thema:
Wenn ich eine Klasse erstelle, die von System.Collections.ObjectModel.Collection erbt und dieser Klasse dann weitere Eigenschaften hinzufüge, werden diese bei xml serialisierung nicht mit gespeichert. Die eigentliche Klasse in meinem Projekt ist natürlich sehr viel größer. Ich habe aber einmal eine Testklasse geschrieben. Ich hoffe jetzt ist es nicht zu viel Code
[highlight=vbnet]
''' <summary>
''' Nur um Fehler beim hinzufügen/ändern der Collection auszugeben
''' </summary>
Public Class EventArgsMessage
Inherits EventArgs
Public Sub New(ByVal Message As String)
Me.Message = Message
End Sub
Public Property Message As String
End Class
<Serializable()> Public Class TestCollection
Inherits System.Collections.ObjectModel.Collection(Of String)
<NonSerialized()> Public Event CollectionError(ByVal sender As Object, ByVal e As EventArgs)
''' <summary>
''' Das ist besagte Property
''' </summary>
Public Property EineProperty As Integer
Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As String)
If String.IsNullOrWhiteSpace(item) Then
RaiseEvent CollectionError(Me, New EventArgsMessage("String can not be added because it is empty"))
Else
MyBase.InsertItem(index, item)
End If
End Sub
Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As String)
If String.IsNullOrWhiteSpace(item) Then
RaiseEvent CollectionError(Me, New EventArgsMessage("String can not be edited because it is empty"))
Else
MyBase.SetItem(index, item)
End If
End Sub
Public Sub XMLExport(ByVal ExportFile As System.IO.FileInfo)
Dim t = Me.GetType
Dim locXmlWriter = New System.Xml.Serialization.XmlSerializer(t)
Dim locXmlFile = New System.IO.StreamWriter(ExportFile.FullName)
Using locXmlFile
locXmlWriter.Serialize(locXmlFile, Me)
locXmlFile.Flush()
locXmlFile.Close()
End Using
End Sub
Public Sub BinExport(ByVal ExportFile As System.IO.FileInfo)
Dim locFs = New IO.FileStream(ExportFile.FullName, IO.FileMode.Create)
Dim locContext = New System.Runtime.Serialization.StreamingContext(Syst em.Runtime.Serialization.StreamingContextStates.Fi le)
Dim locBinaryFormatter = New System.Runtime.Serialization.Formatters.Binary.Bin aryFormatter(Nothing, locContext)
locBinaryFormatter.Serialize(locFs, Me)
locFs.Flush()
locFs.Close()
End Sub
Public Shared Function XMLImport(ByVal ImportFile As System.IO.FileInfo) As TestCollection
Dim locXmlReader = New System.Xml.Serialization.XmlSerializer(GetType(Tes tCollection))
Dim locXmlFile = New System.IO.StreamReader(ImportFile.FullName)
Dim locObject As Object
Using locXmlFile
locObject = locXmlReader.Deserialize(locXmlFile)
locXmlFile.Close()
End Using
Return DirectCast(locObject, TestCollection)
End Function
Public Shared Function BinImport(ByVal ImportFile As System.IO.FileInfo) As TestCollection
Dim locFs = New System.IO.FileStream(ImportFile.FullName, System.IO.FileMode.Open)
Dim locContext = New System.Runtime.Serialization.StreamingContext(Syst em.Runtime.Serialization.StreamingContextStates.Fi le)
Dim locBinaryFormatter = New System.Runtime.Serialization.Formatters.Binary.Bin aryFormatter(Nothing, locContext)
Dim locObject = locBinaryFormatter.Deserialize(locFs)
locFs.Close()
Return DirectCast(locObject, TestCollection)
End Function
End Class
[/highlight]
Wie man sieht wird in der Klasse verhindert, dass leere Strings hinzugefügt werden. Außerdem sind methoden für die xml als auch für die binäre De/Serialisierung implementiert. Wenn man jetzt folgenden Code in einer Konsolenanwendung laufen lässt...
[highlight=vbnet]
Sub Main()
Dim locCollection = New TestCollection
AddHandler locCollection.CollectionError, Sub(sender, e)
Console.WriteLine(DirectCast(e, EventArgsMessage).Message)
End Sub
locCollection.Add("Hallo")
locCollection.Add("Welt")
locCollection.Add("")
locCollection.EineProperty = 123
Dim XmlFile = New System.IO.FileInfo(System.IO.Path.Combine(My.Compu ter.FileSystem.SpecialDirectories.MyDocuments, "TestXml.xml"))
Dim BinFile = New System.IO.FileInfo(System.IO.Path.Combine(My.Compu ter.FileSystem.SpecialDirectories.MyDocuments, "TestBin.bin"))
Try
locCollection.XMLExport(XmlFile)
locCollection.BinExport(BinFile)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Dim XmlImport As TestCollection = Nothing
Dim BinImport As TestCollection = Nothing
Try
XmlImport = TestCollection.XMLImport(XmlFile)
BinImport = TestCollection.BinImport(BinFile)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
If XmlImport IsNot Nothing Then
Console.WriteLine("XmlImport EineProterty=" & XmlImport.EineProperty.ToString)
End If
If BinImport IsNot Nothing Then
Console.WriteLine("BinImport EineProterty=" & BinImport.EineProperty.ToString)
End If
'This program will output:
'String can not be added because it is empty
'XmlImport EineProterty = 0
'BinImport EineProterty = 123
Console.WriteLine()
Console.WriteLine("Press key")
Console.ReadKey()
End Sub
[/highlight]
Wie man sieht wird die Proptery der importierten xml Collection nicht mit gespeichert. Das sieht man auch im xml file. Dort ist nur das ArrayOfString vorhanden. Der Xml-Serialiser speichert also nur die vererbte Item Property der Collection nicht aber die neue Property. Der Binäre Serializer macht alles wunderbar.
Kann man dieses Problem irgendwie umgehen. Ich kenn mich leider mit XML nicht aus. Muss ich da irgendwelche xml include attribute setzen oder ähnliches
Ich hoffe ich habe jetzt keinen Thread Müll erstellt. Dieses Problem muss doch schon mal jemand gehabt haben. Wäre für Hilfe echt dankbar. Auch wenn Sie nur ein Link ist.
Schonmal ein dickes DANKE im vorraus. Freue mich auf Eure Antworten
Beste Grüße
Hendrik
ich wette dieses Problem ist bekannt. Ich konnte in der Suche leider nichts finden. Evtl. einfach die falschen Suchbegriffe. Lasse mich gerne auf einen Thread verweisen.
Zum Thema:
Wenn ich eine Klasse erstelle, die von System.Collections.ObjectModel.Collection erbt und dieser Klasse dann weitere Eigenschaften hinzufüge, werden diese bei xml serialisierung nicht mit gespeichert. Die eigentliche Klasse in meinem Projekt ist natürlich sehr viel größer. Ich habe aber einmal eine Testklasse geschrieben. Ich hoffe jetzt ist es nicht zu viel Code
[highlight=vbnet]
''' <summary>
''' Nur um Fehler beim hinzufügen/ändern der Collection auszugeben
''' </summary>
Public Class EventArgsMessage
Inherits EventArgs
Public Sub New(ByVal Message As String)
Me.Message = Message
End Sub
Public Property Message As String
End Class
<Serializable()> Public Class TestCollection
Inherits System.Collections.ObjectModel.Collection(Of String)
<NonSerialized()> Public Event CollectionError(ByVal sender As Object, ByVal e As EventArgs)
''' <summary>
''' Das ist besagte Property
''' </summary>
Public Property EineProperty As Integer
Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As String)
If String.IsNullOrWhiteSpace(item) Then
RaiseEvent CollectionError(Me, New EventArgsMessage("String can not be added because it is empty"))
Else
MyBase.InsertItem(index, item)
End If
End Sub
Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As String)
If String.IsNullOrWhiteSpace(item) Then
RaiseEvent CollectionError(Me, New EventArgsMessage("String can not be edited because it is empty"))
Else
MyBase.SetItem(index, item)
End If
End Sub
Public Sub XMLExport(ByVal ExportFile As System.IO.FileInfo)
Dim t = Me.GetType
Dim locXmlWriter = New System.Xml.Serialization.XmlSerializer(t)
Dim locXmlFile = New System.IO.StreamWriter(ExportFile.FullName)
Using locXmlFile
locXmlWriter.Serialize(locXmlFile, Me)
locXmlFile.Flush()
locXmlFile.Close()
End Using
End Sub
Public Sub BinExport(ByVal ExportFile As System.IO.FileInfo)
Dim locFs = New IO.FileStream(ExportFile.FullName, IO.FileMode.Create)
Dim locContext = New System.Runtime.Serialization.StreamingContext(Syst em.Runtime.Serialization.StreamingContextStates.Fi le)
Dim locBinaryFormatter = New System.Runtime.Serialization.Formatters.Binary.Bin aryFormatter(Nothing, locContext)
locBinaryFormatter.Serialize(locFs, Me)
locFs.Flush()
locFs.Close()
End Sub
Public Shared Function XMLImport(ByVal ImportFile As System.IO.FileInfo) As TestCollection
Dim locXmlReader = New System.Xml.Serialization.XmlSerializer(GetType(Tes tCollection))
Dim locXmlFile = New System.IO.StreamReader(ImportFile.FullName)
Dim locObject As Object
Using locXmlFile
locObject = locXmlReader.Deserialize(locXmlFile)
locXmlFile.Close()
End Using
Return DirectCast(locObject, TestCollection)
End Function
Public Shared Function BinImport(ByVal ImportFile As System.IO.FileInfo) As TestCollection
Dim locFs = New System.IO.FileStream(ImportFile.FullName, System.IO.FileMode.Open)
Dim locContext = New System.Runtime.Serialization.StreamingContext(Syst em.Runtime.Serialization.StreamingContextStates.Fi le)
Dim locBinaryFormatter = New System.Runtime.Serialization.Formatters.Binary.Bin aryFormatter(Nothing, locContext)
Dim locObject = locBinaryFormatter.Deserialize(locFs)
locFs.Close()
Return DirectCast(locObject, TestCollection)
End Function
End Class
[/highlight]
Wie man sieht wird in der Klasse verhindert, dass leere Strings hinzugefügt werden. Außerdem sind methoden für die xml als auch für die binäre De/Serialisierung implementiert. Wenn man jetzt folgenden Code in einer Konsolenanwendung laufen lässt...
[highlight=vbnet]
Sub Main()
Dim locCollection = New TestCollection
AddHandler locCollection.CollectionError, Sub(sender, e)
Console.WriteLine(DirectCast(e, EventArgsMessage).Message)
End Sub
locCollection.Add("Hallo")
locCollection.Add("Welt")
locCollection.Add("")
locCollection.EineProperty = 123
Dim XmlFile = New System.IO.FileInfo(System.IO.Path.Combine(My.Compu ter.FileSystem.SpecialDirectories.MyDocuments, "TestXml.xml"))
Dim BinFile = New System.IO.FileInfo(System.IO.Path.Combine(My.Compu ter.FileSystem.SpecialDirectories.MyDocuments, "TestBin.bin"))
Try
locCollection.XMLExport(XmlFile)
locCollection.BinExport(BinFile)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Dim XmlImport As TestCollection = Nothing
Dim BinImport As TestCollection = Nothing
Try
XmlImport = TestCollection.XMLImport(XmlFile)
BinImport = TestCollection.BinImport(BinFile)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
If XmlImport IsNot Nothing Then
Console.WriteLine("XmlImport EineProterty=" & XmlImport.EineProperty.ToString)
End If
If BinImport IsNot Nothing Then
Console.WriteLine("BinImport EineProterty=" & BinImport.EineProperty.ToString)
End If
'This program will output:
'String can not be added because it is empty
'XmlImport EineProterty = 0
'BinImport EineProterty = 123
Console.WriteLine()
Console.WriteLine("Press key")
Console.ReadKey()
End Sub
[/highlight]
Wie man sieht wird die Proptery der importierten xml Collection nicht mit gespeichert. Das sieht man auch im xml file. Dort ist nur das ArrayOfString vorhanden. Der Xml-Serialiser speichert also nur die vererbte Item Property der Collection nicht aber die neue Property. Der Binäre Serializer macht alles wunderbar.
Kann man dieses Problem irgendwie umgehen. Ich kenn mich leider mit XML nicht aus. Muss ich da irgendwelche xml include attribute setzen oder ähnliches
Ich hoffe ich habe jetzt keinen Thread Müll erstellt. Dieses Problem muss doch schon mal jemand gehabt haben. Wäre für Hilfe echt dankbar. Auch wenn Sie nur ein Link ist.
Schonmal ein dickes DANKE im vorraus. Freue mich auf Eure Antworten
Beste Grüße
Hendrik
Comment