XmlSerializer - Ich stehe (als Ochse) vor dem Berg

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von JRole.

    XmlSerializer - Ich stehe (als Ochse) vor dem Berg

    Moinsen zusammen,

    ich habe früher - als ich noch richtig fett in der Materie war - Immer den BinaryFormatter benutzt, um meine Objekte zu sichern. Das scheint jetzt nicht mehr zu gehen (BinaryFormatter ist veraltet).

    Gut, speichern wir das ganze als XML ab. Steht auch in der MSDN: als Ersatz für den BinaryFormatter soll der XmlSerializer verwendet werden. Gelesen, getan, und dann kommt der Berg.

    Ich bekomme die Meldung: "InvalidOperationException: System.RuntimeType is inaccessible due to its protection level. Only public types can be processed." Seltsam, wenn doch wirklich alles als Public deklariert ist.

    Der Code Speichern:

    VB.NET-Quellcode

    1. Public Function Save(Optional ByVal Overwrite As Boolean = False) As Boolean
    2. Dim Result As Boolean = False
    3. Dim Serializer As Xml.Serialization.XmlSerializer = Nothing
    4. If IO.File.Exists(_Path) Then
    5. If Overwrite Then IO.File.Delete(_Path)
    6. Using Stream = New IO.FileStream(_Path, IO.FileMode.CreateNew)
    7. Serializer = New Xml.Serialization.XmlSerializer(_List.GetType)
    8. Serializer.Serialize(Stream, _List) ' <-- hier knallt's
    9. Stream.Close()
    10. End Using
    11. Result = True
    12. End If
    13. Return Result
    14. End Function


    Die Klasse die gespeichert werden soll

    VB.NET-Quellcode

    1. <Serializable> Public Class Field
    2. Public ReadOnly Property ID As Integer
    3. Public Property Name As String
    4. Public Property Type As System.Type
    5. Public Property Ignore As Boolean
    6. Public Sub New()
    7. _ID = -1
    8. End Sub
    9. Public Sub New(ByVal ID As Integer)
    10. _ID = ID
    11. _Name = ""
    12. _Type = Nothing
    13. _Ignore = False
    14. End Sub
    15. Public Sub New(ByVal ID As Integer, ByVal Name As String, ByVal Type As System.Type, ByVal Ignore As Boolean)
    16. _ID = ID
    17. _Name = Name
    18. _Type = Type
    19. _Ignore = Ignore
    20. End Sub
    21. End Class


    Wo liegt mein Denkfehler? Oder habe ich das Prinzip nicht verstanden?

    Danke vorab,
    Jens
    Und wie ist _List deklariert?
    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.
    Check. Oder besser: gecheckt, aber keine Änderung. Ich hab' das ganze mal in ein Demo-Projekt gepackt - Siehe Anhang.

    Am liebsten hätte ich aber den BinaryFormatter zurück :) Bin für jede Aufklärung dankbar. Man lernt ja immer dazu und wer weiß schon, für was es gut ist!

    Jens
    Dateien
    • CSVImport.zip

      (7,56 kB, 193 mal heruntergeladen, zuletzt: )
    MyFault. Der Typ Type kann anscheinend von Haus aus nicht (de)serialisiert werden.
    Ich verwende zwar bevorzugt JSON, aber hab nicht getestet, ob damit der genannte Typ verarbeitet werden kann. Und Binary? Wusste gar nicht, dass der nicht mehr geht.
    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.
    Speichere doch Type.Name als String und gib der Klasse eine String-To-Type-Property.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany: So habe ich es jetzt gemacht. Aber auch mit dem JSONSerializer. Sieht einfach auch besser aus ;)

    Als würde das was zählen!

    Edit: Was mir jetzt aber noch fehlt, um die Verwendung einfacher zu machen: Kann man Properties von der Serialisierung ausnehmen? Hier also eben die Type-Property.

    JRole
    @JRole So was:

    VB.NET-Quellcode

    1. <XmlIgnore>
    2. <NonSerialized>
    3. Public Property Ignore As Boolean
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @petaod und @all

    Danke! Bei etwas genauerem Nachdenken ist es nicht nötig. Habe ich aber erst nach einigem Lesen und Grübeln gemerkt. Für alle, die es interessiert, System.Type kann man serialisieren. Ist aber umständlicher als das explizite Casten.

    VB.NET-Quellcode

    1. <System.Runtime.Serialization.DataContract> Public Class SerializableType
    2. Private Type As System.Type
    3. <System.Runtime.Serialization.DataMember> Public Property FullName As String
    4. Get
    5. If Me.Type Is Nothing Then
    6. Return Nothing
    7. Else
    8. Return Me.Type.FullName
    9. End If
    10. End Get
    11. Set(value As String)
    12. If value Is Nothing Then
    13. Me.Type = Nothing
    14. Else
    15. Me.Type = System.Type.GetType(value)
    16. End If
    17. End Set
    18. End Property
    19. Public Sub New()
    20. Me.Type = Nothing
    21. End Sub
    22. Public Sub New(ByVal Type As System.Type)
    23. Me.Type = Type
    24. End Sub
    25. Public Shared Narrowing Operator CType(ByVal sType As SerializableType) As System.Type
    26. Return sType.Type
    27. End Operator
    28. Public Shared Narrowing Operator CType(ByVal sType As Type) As SerializableType
    29. Return New SerializableType(sType)
    30. End Operator
    31. Public Shared Operator =(ByVal TypeA As SerializableType, ByVal TypeB As SerializableType) As Boolean
    32. If System.Object.ReferenceEquals(TypeA, TypeB) Then
    33. Return True
    34. End If
    35. If TypeA Is Nothing OrElse TypeB Is Nothing Then
    36. Return False
    37. End If
    38. Return TypeA.GetType = TypeB.GetType
    39. End Operator
    40. Public Shared Operator <>(ByVal TypeA As SerializableType, ByVal TypeB As SerializableType) As Boolean
    41. Return Not (TypeA = TypeB)
    42. End Operator
    43. Public Overrides Function GetHashCode() As Integer
    44. Return Me.Type.GetHashCode()
    45. End Function
    46. Public Overrides Function Equals(obj As Object) As Boolean
    47. Dim Casted As SerializableType = Nothing
    48. If obj Is Nothing Then
    49. Return False
    50. End If
    51. Casted = New SerializableType(obj.GetType)
    52. If Casted = Nothing Then
    53. Return False
    54. End If
    55. Return Casted Is Me.Type
    56. End Function
    57. Public Overloads Function Equals(ByVal SerializableType As SerializableType) As Boolean
    58. If SerializableType Is Nothing Then
    59. Return False
    60. End If
    61. Return Me.Type Is SerializableType
    62. End Function
    63. End Class


    Gruß, JRole

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