XML Serializer-Problem: keine Serialisierung zusätzlicher Infos für eine geerbte List(Of T)

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Kasi.

    XML Serializer-Problem: keine Serialisierung zusätzlicher Infos für eine geerbte List(Of T)

    Hallo zusammen,

    ich habe ein kleines Problem mit dem XML Serializer, bei dem ich es aber auch belassen will; der BinaryFormatter k**zt mich nämlich mit seinem »Ich will aber, dass alle relevanten Klassen mit dem <Serializable>-Attribut versehen sind.« ziemlich an.
    Ich habe eine von List(Of T) abgeleitete Klasse:

    VB.NET-Quellcode

    1. Public Class TestClass : Inherits List(Of Integer)
    2. Public Property TestString As String = "foobar"
    3. End Class


    Diese serialisiere ich mit

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim TestClassInstance As New TestClass
    3. TestClassInstance.AddRange({1, 2, 3})
    4. Serialize(TestClassInstance)
    5. End Sub
    6. Private Sub Serialize(Of T)(TargetObject As T)
    7. Using StringWriter As New IO.StringWriter
    8. Dim XmlSerializer = New Xml.Serialization.XmlSerializer(GetType(T))
    9. XmlSerializer.Serialize(StringWriter, TargetObject)
    10. IO.File.WriteAllText("outputfile.txt", StringWriter.ToString)
    11. End Using
    12. End Sub

    Das Problem: Die Zusatzklasseninstanzinfo TestString wird nicht mit serialisiert. Wo liegt mein Fehler? Oder besser gefragt: Wie macht man es richtig, ohne einen WrapperContainer herzunehmen, in den man die Info verschiebt (was, glaube ich, geht, aber m.E. Overkill wäre) und den stattdessen zu serialisieren?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Moin,

    VB.NET-Quellcode

    1. ​Public Class TestClassExtension
    2. Public Property Ints As New List(Of Integer)
    3. End Class


    VB.NET-Quellcode

    1. Public Class TestClass : Inherits TestClassExtension
    2. Public Property Text As String = "Test"
    3. End Class


    So würde es gehen. Ich denke mal, der Serializer braucht wirklich die Übergeordnete Klasse für die List(Of Integer), da er sonst die Items in der List direkt serialisiert und sie nicht als Klasse anerkennt.
    Da ist ja noch ein Thema von mir offen …
    Da bei stackoverflow auf die Details dieses Problems eingegangen wird, aber auch klargemacht wird, dass das so ist, wie hier schon erwähnt wurde, ist die Sache erledigt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Propier mal folgendes

    VB.NET-Quellcode

    1. <System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0"),
    2. System.SerializableAttribute(),
    3. System.Diagnostics.DebuggerStepThroughAttribute(),
    4. System.ComponentModel.DesignerCategoryAttribute("code"),
    5. System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)>
    6. Public Class TestClass : Inherits List(Of Integer)
    7. <System.Xml.Serialization.XmlElementAttribute(Form:=System.Xml.Schema.XmlSchemaForm.Unqualified)>
    8. Public Property TestString As String = "foobar"
    9. End Class


    Dann sollte die Serialisierung klappen.

    EDIT: Okay, vergiss es. Habs gerade getestet und es wird offenbar auch ignoriert.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Yanbel“ ()

    das funktionert indem mann eine 'Structure' anlegt, sonnst wüsste ich auch keine andere Lösung

    hier ein Bsp. mit einer Listview

    VB.NET-Quellcode

    1. Imports System.Xml
    2. Imports System.IO
    3. Public Class Form1
    4. Public Structure DataItem
    5. Public FieldName1 As System.String
    6. Public FieldName2 As System.String
    7. Public FieldName3 As System.String
    8. Public Shared Function FromListViewItem(ByVal Item As System.Windows.Forms.ListViewItem) As DataItem
    9. Dim DataItem As DataItem = New DataItem
    10. DataItem.FieldName1 = Item.SubItems(0).Text
    11. DataItem.FieldName2 = Item.SubItems(1).Text
    12. DataItem.FieldName3 = Item.SubItems(2).Text
    13. Return DataItem
    14. End Function
    15. Public Function AsListViewItem() As System.Windows.Forms.ListViewItem
    16. Dim ListViewItem As System.Windows.Forms.ListViewItem = New System.Windows.Forms.ListViewItem(FieldName1)
    17. ListViewItem.SubItems.Add(FieldName2)
    18. ListViewItem.SubItems.Add(FieldName3)
    19. Return ListViewItem
    20. End Function
    21. End Structure
    22. Dim DataItemsList As System.Collections.Generic.List(Of DataItem) = _
    23. New System.Collections.Generic.List(Of DataItem)
    24. Dim XmlSerializer As System.Xml.Serialization.XmlSerializer = _
    25. New System.Xml.Serialization.XmlSerializer(GetType(System.Collections.Generic.List(Of DataItem)))
    26. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    27. 'sample Data
    28. With ListView1
    29. .Items.Clear()
    30. .Columns.Clear()
    31. .View = View.Details
    32. .Columns.Add("Spalte 0")
    33. .Columns.Add("Spalte 1")
    34. .Columns.Add("Spalte 2")
    35. For i As Integer = 0 To 5
    36. Dim Li As New ListViewItem
    37. Li.Text = "Item " & i.ToString & "0"
    38. For j As Integer = 0 To 3
    39. Li.SubItems.Add("Item " & i.ToString & "." & (j + 1).ToString)
    40. Next
    41. .Items.Add(Li)
    42. Next
    43. .Refresh()
    44. End With
    45. End Sub
    46. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    47. 'write XML
    48. Dim DataItemsList As System.Collections.Generic.List(Of DataItem) = _
    49. New System.Collections.Generic.List(Of DataItem)
    50. For Each ListViewItem As System.Windows.Forms.ListViewItem In ListView1.Items
    51. DataItemsList.Add(DataItem.FromListViewItem(ListViewItem))
    52. Next
    53. Dim XmlSerializer As System.Xml.Serialization.XmlSerializer = _
    54. New System.Xml.Serialization.XmlSerializer(GetType(System.Collections.Generic.List(Of DataItem)))
    55. Dim StreamWriter As System.IO.StreamWriter = _
    56. New System.IO.StreamWriter("E:\TestFolder\test3.Xml", False)
    57. XmlSerializer.Serialize(StreamWriter, DataItemsList)
    58. 'For Each DataItem As DataItem In DataItemsList
    59. ' Debug.Print(DataItem.FieldName1)
    60. 'Next
    61. StreamWriter.Flush()
    62. StreamWriter.Close()
    63. StreamWriter.Dispose()
    64. End Sub
    65. Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
    66. 'read XML
    67. Dim StreamReader As System.IO.StreamReader = _
    68. New System.IO.StreamReader("E:\TestFolder\test3.xml")
    69. Dim XmlReader As System.Xml.XmlReader = _
    70. System.Xml.XmlReader.Create(StreamReader)
    71. With ListView1
    72. .Items.Clear()
    73. .Columns.Clear()
    74. .View = View.Details
    75. .Columns.Add("Spalte 0")
    76. .Columns.Add("Spalte 1")
    77. .Columns.Add("Spalte 2")
    78. End With
    79. If XmlSerializer.CanDeserialize(XmlReader) Then
    80. DataItemsList = XmlSerializer.Deserialize(XmlReader)
    81. For Each DataItem As DataItem In DataItemsList
    82. ListView1.Items.Add(DataItem.AsListViewItem)
    83. Next
    84. Else
    85. 'Invalid file type
    86. End If
    87. XmlReader.Close()
    88. StreamReader.Close()
    89. StreamReader.Dispose()
    90. End Sub
    91. End Class