| 

.NET C# Java Javascript Exception

0
Hallo,

ich arbeite seit kurzem mit JSON-Daten in VB und beziehe diese aus einer fremden Quelle per REST. Das einzeln je Objekt-Type implementierte Deserialisieren funktioniert. Um das Abholen der Daten und Deserialisieren für weitere Objekt-Typen nicht neu machen zu müssen, habe ich testweise eine generische Klasse für das Deserialisieren der Objekte aus den JSON-Daten erstellt. Die abgeleiteten Klassen spezialisieren dann nur den zu verarbeitenden Typ. So weit so gut. Doch leider kommt beim Deserialiseren mittels generischer Basisklasse dann eine Fehlermeldung nach dem Schema:

Der Typ "..." kann nur von einem Typ erben, der mit DataContractAttribute oder SerializableAttribute gekennzeichnet ist. Sie sollten den Basistyp "..." mit DataContractAttribute oder SerializableAttribute kennzeichnen oder diese aus dem abgeleiteten Typ entfernen.

Ist das mit der gen. Basisklasse an dieser Stelle doch keine gute Idee oder was habe ich übersehen?
28.02.2011
traudi 231 4
1 Antwort
2
Hast Du die Basisklasse mit dem DataContractAttribute bzw. SerializableAttribute ausgestattet? Kannst Du vielleicht ein einfaches Beispiel posten?

EDIT:
Danke für das Beispiel. Noch besser wäre es gewesen, Du hättest es per Edit Deiner Frage hinzugefügt.

Deiner Basisklasse fehlt das DataContractAttribute:

Unmarked types (types without the DataContractAttribute attribute) can inherit from types that do have this attribute; however, the reverse is not permitted: types with the attribute cannot inherit from unmarked types. This rule is enforced primarily to ensure backward compatibility with code written in earlier versions of .NET Framework.
Quelle: MSDN


Ansonsten wäre aber meine Empfehlung, die (De-)Serialisierung aus den Datenklassen herauszuhalten, also statt der Basisklasse einen dedizierten Deserializer zu schreiben mit einer Methode (sorry, C#-Syntax)

T Deserialize<T>(string json)

Zumindest aus Deinem Beispielcode kann ich keinen Grund herauslesen, warum der Deserialisierungscode in der Basisklasse stecken muss, und statische Methoden erschweren die Testbarkeit des Codes, da Du immer an die konkrete Implementierung gebunden bist. Für die vorgeschlagene Deserialize-Methode hingegen könntest Du auch ein Interface definieren und dieses bei Bedarf in Unit-Tests mocken.
28.02.2011
Matthias Hlawatsch 8,4k 2 8
hier die Basisklasse:

Public Class GenericItem(Of T)
Public Shared Function Load(ByVal Json As String) As T
End Function
End Class

und hier die abgeleitete:

<DataContract()> _
Public Class ProjectList
Inherits GenericItem(Of ProjectList)

<DataMember(name:="value", order:=0)> _
Friend Value As Integer

End Class

traudi 28.02.2011
Das mit dem fehlenden DataContractAttribute in der Basisklasse war der entscheidende Tip. Vielen Dank!
traudi 01.03.2011
Bitteschön! Freut mich, dass ich helfen konnte. Vielleicht magst Du die Antwort auch noch durch Klick auf das Häkchen unterhalb der Bewertung "offiziell" akzeptieren?
Matthias Hlawatsch 01.03.2011

Stelle deine Vb-Frage jetzt!