Hi,
in diesem Tutorial möchte ich Euch das Arbeiten mit JSON-Dateien näher bringen. JSON ist die Abkürzung für
Wie sieht eine JSON-Datei aus?
Dies ist die Abbildung einer
Wie in der JSON-Datei zu sehen ist, hat die Car-Instanz die
Die Grundlegende Schreibweise ist:
Wobei Werte vom Typ String mit Anführungszeichen und numerische Werte ohne geschrieben werden. Die jeweiligen
Soweit zur Theorie, nun zur Praxis...
Um Newtonsoft.JSON im Projekt nutzen zu können, ist es notwendig, die Library zu importieren...
Zusätzlich muss der Namespace importiert werden.
Der Serialisierungsvorgang
Zu sehen ist die Erzeugung eines Arrays vom
Der Deserialisierungsvorgang
Der zuvor gespeicherete JSON-String wird in die
Serialisieren/Deserialisieren von Listen/Arrays
Erzeugt werden 3 Car-Instanzen, welche in eine Liste gepackt werden. Zum serialisieren wird nun einfach die Liste
Die erzeugten JSON-Daten sehen so aus:
Die
Erzeugen von Klassen für nicht selbsterstellte JSON-Daten
Hat man einen fremden JSON-String und will man mit diesen Daten arbeiten, so bietet es sich an, sich Klassen für diese Daten erzeugen zu lassen. Ich nutze dazu diesen Service https://jsonutils.com/ und diese Testdaten developer.mozilla.org/en-US/do…n/JavaScript/Objects/JSON Die JSON-Daten werden kopiert und bei jsonutils eingefügt. Auf Basis der Daten werden nun Klassen generiert, welche man in sein Projekt einfügen kann. Lediglich sollte man dem
Um die JSON-Daten auf die Klassen zu
Abweichende Property-Namen
Der Deserialisierungsvorgang kann nur korrekt ablaufen, wenn die Property-Namen in den VB-Klassen auf die Property-Namen in den JSON-Daten passen. Sonst schlägt der Vorgang fehl. Basierend auf dem
Wie zu sehen ist, hat
Um dies nun zu beheben, nimmt man sich Attribute zur Hilfe.
Der Property
Abweichende Property-Namen sind somit kein Problem.
Arbeiten mit JSON-Daten ohne Mapping auf Klassen
Falls man keine VB-Klassen für die JSON-Daten erzeugen möchte, gibt es folgende Möglichkeit (basierend auf SuperheroSquad)
Man nutzt
.NET Implementierung von JSON
Wer keine externe LIbrary benutzen möchte, dem bietet das .NET-Framework eine eigene Möglichkeit, mit JSON-Daten zu arbeiten. Benötigt wird ein Verweis auf das .NET-Assembly
Der Serialisierungs- Deserialisierungsvorgang ist fast der selbe wie bei Newtonsoft.Json.
Auch hier gibt es die Möglichkeit, untypisiert zu arbeiten, hierauf werde ich aber nicht näher eingehen, da mir hier selbst die Erfahrung fehlt und ich die interne Implementierung nicht nutze. Falls Bedarf besteht, werde ich mich damit befassen.
Dieses Thema ist hier nicht erschöpft behandelt worden, jedoch sollte eine grundlegende Übersicht geschaffen worden sein, wie mit JSON-Daten gearbeitet werden kann. Sollten Fehler in meinen Ausführungen sein, so bitte ich um Korrektur. Ich bedanke mich fürs Lesen!
Danny!
in diesem Tutorial möchte ich Euch das Arbeiten mit JSON-Dateien näher bringen. JSON ist die Abkürzung für
JavaScript Object Notation
. JSON ist ähnlich zu XML und dient dem Zweck, Daten strukturiert und lesbar zu speichern. Die meisten Webanwendungen nutzen JSON, um Daten zu versenden, bzw. zu empfangen. Auch .NET hat Klassen, um mit JSON zu arbeiten. Jedoch gibt es eine 3rd-Party
LIbrary, die ich bevorzugt einsetze newtonsoft.com/json Dieses Tutorial basiert auf dieser Library.Wie sieht eine JSON-Datei aus?
Dies ist die Abbildung einer
Car-Instanz
in JSON, welche in VB so aussieht.VB.NET-Quellcode
- Public Class Car
- Public Property Color As Color
- Public Property Engine As Engine
- Public Property Brand As String
- Public Property Wheels As Wheel()
- Public Sub New(color As Color, engine As Engine, brand As String, wheels As Wheel())
- Me.Color = color
- Me.Engine = engine
- Me.Brand = brand
- Me.Wheels = wheels
- End Sub
- End Class
- Public Class Wheel
- Public Brand As String
- Public Sub New(brand As String)
- Me.Brand = brand
- End Sub
- End Class
- Public Class Engine
- Public Property CylinderCount As Integer
- Public Property FuelType As FuelTypes
- Public Sub New(cylinderCount As Integer, fuelType As FuelTypes)
- Me.CylinderCount = cylinderCount
- Me.FuelType = fuelType
- End Sub
- End Class
- Public Enum FuelTypes
- Diesel = 0
- Gas = 1
- Electric = 2
- End Enum
Wie in der JSON-Datei zu sehen ist, hat die Car-Instanz die
Property Color
, welche mit Black
festgelegt wurde, eine Engine-Instanz
, welche selbst wieder ein komplexer Typ
ist (zu erkennen an den geschweiften Klammern), eine Property Brand
vom Typ String
mit dem Wert BMW
und ein Array vom Typ Wheel
(ein Array ist mit eckigen Klammern gekennzeichnet). Die Color-Property ist vom Typ Color
, wird aber als String
in der JSON-Datei gespeichert.Die Grundlegende Schreibweise ist:
"Property": "Wert"
Wobei Werte vom Typ String mit Anführungszeichen und numerische Werte ohne geschrieben werden. Die jeweiligen
"Property": "Wert" Paare
werden durch Kommas voneinander getrennt. Der Speichervorgang einer JSON-Datei wird Serialize
und der Lesevorgang Deserialize
genannt.Soweit zur Theorie, nun zur Praxis...
Um Newtonsoft.JSON im Projekt nutzen zu können, ist es notwendig, die Library zu importieren...
Zusätzlich muss der Namespace importiert werden.
Der Serialisierungsvorgang
VB.NET-Quellcode
- Imports Newtonsoft.Json
- Imports System.IO
- Public Class Form1
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim wheels1 As Wheel() = {New Wheel("Dunlop"), New Wheel("Dunlop"), New Wheel("Dunlop"), New Wheel("Dunlop")}
- Dim engine1 As New Engine(6, FuelTypes.Gas)
- Dim car1 As New Car(Color.Black, engine1, "BMW", wheels1)
- Dim json As String = JsonConvert.SerializeObject(car1)
- File.WriteAllText("car1.json", json)
- End Sub
- End Class
Zu sehen ist die Erzeugung eines Arrays vom
Typ Wheel
, eine Instanz vom Typ Engine
und die Car-Instanz
selbst. Der Aufruf vom JsonConvert.SerializeObject(car1)
gibt einen String zurück, welcher genau dem am Anfang gezeigten entspricht. Dieser String kann nun in eine Datei geschrieben werden. Die Instanz ist somit serialisiert.Der Deserialisierungsvorgang
Der zuvor gespeicherete JSON-String wird in die
Variable json
eingelesen. Nun folgt der Aufruf von JsonConvert.DeserializeObject(Of Car)(json)
. Dies ist eine generische
Funktion, zu erkennen an dem Schlüsselwort Of
. Hier muss der Typ angegeben werden, welcher am Ende des Deserialiserungsvorgang herauskommen soll. Passen die JSON-Daten nicht auf diesen Typ, wird eine Ausnahme
ausgelöst. Dies alles geschieht intern in der Newtonsoft.JSON-Library. War der Vorgang erfolgreich, so habt ihr das zuvor gespeicherte Objekt wiederhergestellt. Der Deserialisierungsvorgang ist beendet.Serialisieren/Deserialisieren von Listen/Arrays
VB.NET-Quellcode
- Imports Newtonsoft.Json
- Imports System.IO
- Public Class Form1
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim wheels1 As Wheel() = {New Wheel("Dunlop"), New Wheel("Dunlop"), New Wheel("Dunlop"), New Wheel("Dunlop")}
- Dim engine1 As New Engine(6, FuelTypes.Gas)
- Dim car1 As New Car(Color.Black, engine1, "BMW", wheels1)
- Dim wheels2 As Wheel() = {New Wheel("Bridgestone"), New Wheel("Bridgestone"), New Wheel("Bridgestone"), New Wheel("Bridgestone")}
- Dim engine2 As New Engine(0, FuelTypes.Electric)
- Dim car2 As New Car(Color.White, engine2, "Tesla", wheels2)
- Dim wheels3 As Wheel() = {New Wheel("Continental"), New Wheel("Continental"), New Wheel("Continental"), New Wheel("Continental")}
- Dim engine3 As New Engine(4, FuelTypes.Diesel)
- Dim car3 As New Car(Color.Blue, engine3, "Mazda", wheels3)
- Dim carList As New List(Of Car) From {car1, car2, car3}
- Dim json As String = JsonConvert.SerializeObject(carList)
- File.WriteAllText("cars.json", json)
- End Sub
- Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
- Dim json As String = File.ReadAllText("cars.json")
- Dim carList As List(Of Car) = JsonConvert.DeserializeObject(Of List(Of Car))(json)
- End Sub
- End Class
Erzeugt werden 3 Car-Instanzen, welche in eine Liste gepackt werden. Zum serialisieren wird nun einfach die Liste
carList
an die Funktion JsonConvert.SerializeObject(carList)
übergeben und der erzeugte JSON-String gespeichert. Um nun wieder eine Liste zurückzubekommen, ändert man in der generischen Funktion JsonConvert.DeserializeObject(Of List(Of Car))(json)
den Zieltyp auf List(Of Car)
.Die erzeugten JSON-Daten sehen so aus:
Quellcode
- [
- {
- "Color": "Black",
- "Engine": {
- "CylinderCount": 6,
- "FuelType": 1
- },
- "Brand": "BMW",
- "Wheels": [
- {
- "Brand": "Dunlop"
- },
- {
- "Brand": "Dunlop"
- },
- {
- "Brand": "Dunlop"
- },
- {
- "Brand": "Dunlop"
- }
- ]
- },
- {
- "Color": "White",
- "Engine": {
- "CylinderCount": 0,
- "FuelType": 2
- },
- "Brand": "Tesla",
- "Wheels": [
- {
- "Brand": "Bridgestone"
- },
- {
- "Brand": "Bridgestone"
- },
- {
- "Brand": "Bridgestone"
- },
- {
- "Brand": "Bridgestone"
- }
- ]
- },
- {
- "Color": "Blue",
- "Engine": {
- "CylinderCount": 4,
- "FuelType": 0
- },
- "Brand": "Mazda",
- "Wheels": [
- {
- "Brand": "Continental"
- },
- {
- "Brand": "Continental"
- },
- {
- "Brand": "Continental"
- },
- {
- "Brand": "Continental"
- }
- ]
- }
- ]
Die
eckige Klammer
am Anfang gibt zu erkennen, dass es sich hier um ein Liste, bzw. Array handelt.Erzeugen von Klassen für nicht selbsterstellte JSON-Daten
Hat man einen fremden JSON-String und will man mit diesen Daten arbeiten, so bietet es sich an, sich Klassen für diese Daten erzeugen zu lassen. Ich nutze dazu diesen Service https://jsonutils.com/ und diese Testdaten developer.mozilla.org/en-US/do…n/JavaScript/Objects/JSON Die JSON-Daten werden kopiert und bei jsonutils eingefügt. Auf Basis der Daten werden nun Klassen generiert, welche man in sein Projekt einfügen kann. Lediglich sollte man dem
Rootobject
auf der jsonutils-Seite Example
genannt einen anderen Namen geben. Ich lege diesen auf SuperheroSquad
fest und speichere den JSON-String in einer Datei superhero.json
. Die JSON-Daten und die generierten Klassen sehen so aus:Quellcode
- {
- "squadName": "Super hero squad",
- "homeTown": "Metro City",
- "formed": 2016,
- "secretBase": "Super tower",
- "active": true,
- "members": [
- {
- "name": "Molecule Man",
- "age": 29,
- "secretIdentity": "Dan Jukes",
- "powers": [
- "Radiation resistance",
- "Turning tiny",
- "Radiation blast"
- ]
- },
- {
- "name": "Madame Uppercut",
- "age": 39,
- "secretIdentity": "Jane Wilson",
- "powers": [
- "Million tonne punch",
- "Damage resistance",
- "Superhuman reflexes"
- ]
- },
- {
- "name": "Eternal Flame",
- "age": 1000000,
- "secretIdentity": "Unknown",
- "powers": [
- "Immortality",
- "Heat Immunity",
- "Inferno",
- "Teleportation",
- "Interdimensional travel"
- ]
- }
- ]
- }
VB.NET-Quellcode
- Public Class Member
- Public Property name As String
- Public Property age As Integer
- Public Property secretIdentity As String
- Public Property powers As String()
- End Class
- Public Class SuperheroSquad
- Public Property squadName As String
- Public Property homeTown As String
- Public Property formed As Integer
- Public Property secretBase As String
- Public Property active As Boolean
- Public Property members As Member()
- End Class
Um die JSON-Daten auf die Klassen zu
mappen
genügt es, das bereits gelernte anzuwenden:VB.NET-Quellcode
- Imports Newtonsoft.Json
- Imports System.IO
- Public Class Form1
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim json As String = File.ReadAllText("superheroes.json")
- Dim squad As SuperheroSquad = JsonConvert.DeserializeObject(Of SuperheroSquad)(json)
- End Sub
- End Class
Abweichende Property-Namen
Der Deserialisierungsvorgang kann nur korrekt ablaufen, wenn die Property-Namen in den VB-Klassen auf die Property-Namen in den JSON-Daten passen. Sonst schlägt der Vorgang fehl. Basierend auf dem
SuperheroSquad
-Beispiel ändere ich in der Klasse Member
die Property secretIdentity
auf secretName
VB.NET-Quellcode
- Public Class Member
- Public Property name As String
- Public Property age As Integer
- Public Property secretName As String
- Public Property powers As String()
- End Class
- Public Class SuperheroSquad
- Public Property squadName As String
- Public Property homeTown As String
- Public Property formed As Integer
- Public Property secretBase As String
- Public Property active As Boolean
- Public Property members As Member()
- End Class
Wie zu sehen ist, hat
secretName
keine Wert. Es wurde während des Deserialisierungsvorgangs keine
Ausnahme ausgelöst, sondern die fehlende Property einfach ignoriert. Es sollte stets geprüft werden, ob die erzeugten Klassen auch wirklich auf die JSON-Daten passen. Die Klassenerzeugung auf jsonutils ist nicht immer 100% korrekt.Um dies nun zu beheben, nimmt man sich Attribute zur Hilfe.
VB.NET-Quellcode
- Public Class Member
- Public Property name As String
- Public Property age As Integer
- <JsonProperty("secretIdentity")>
- Public Property secretName As String
- Public Property powers As String()
- End Class
- Public Class SuperheroSquad
- Public Property squadName As String
- Public Property homeTown As String
- Public Property formed As Integer
- Public Property secretBase As String
- Public Property active As Boolean
- Public Property members As Member()
- End Class
Der Property
secretName
wurde das Attribut <JsonProperty("secretIdentity")>
hinzugefügt. Nun wird wieder korrekt gemappt. Bei Deserialisierungsvorgang wird das Attribut, falls vorhanden, berücksichtigt. Abweichende Property-Namen sind somit kein Problem.
Arbeiten mit JSON-Daten ohne Mapping auf Klassen
Falls man keine VB-Klassen für die JSON-Daten erzeugen möchte, gibt es folgende Möglichkeit (basierend auf SuperheroSquad)
VB.NET-Quellcode
- Imports Newtonsoft.Json.Linq
- Imports Newtonsoft.Json
- Imports System.IO
- Public Class Form1
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim json As String = File.ReadAllText("superheroes.json")
- Dim data As JObject = DirectCast(JsonConvert.DeserializeObject(json), JObject)
- Dim squadName As JToken = data("squadName")
- Dim members As JToken = data("members")
- Debug.Print(squadName.ToString())
- For Each x As JToken In members
- Debug.Print(x("secretIdentity").ToString() & " " & x("age").ToString())
- Next
- End Sub
- End Class
Man nutzt
DirectCast(JsonConvert.DeserializeObject(json), JObject)
um den JSON-String zu parsen. Diese Funktion gibt den Typ Object
zurück und sollte daher auf den Typ JObject
gecasted werden. Dieses JObject enthält JTokens
, welche die einzelnen Properties mit ihren Werten darstellen. Hier aufpassen, es wird der Newtonsoft.Json.Linq-Namespace
benötigt. Aus meiner Sicht ist diese Vorgehensweise nicht die eleganteste, aber bietet sich an, wenn man nur einen bestimmten Wert in einer JSON-Datei benötigt. Ich bevorzuge das Mapping auf Klassen. .NET Implementierung von JSON
Wer keine externe LIbrary benutzen möchte, dem bietet das .NET-Framework eine eigene Möglichkeit, mit JSON-Daten zu arbeiten. Benötigt wird ein Verweis auf das .NET-Assembly
System.Web.Extensions
und der Import des System.Web.Script.Serialization
-Namespaces.Der Serialisierungs- Deserialisierungsvorgang ist fast der selbe wie bei Newtonsoft.Json.
VB.NET-Quellcode
- Imports System.Web.Script.Serialization
- Imports System.IO
- Public Class Form1
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim json As String = File.ReadAllText("superheroes.json")
- Dim jsonSerializer As New JavaScriptSerializer()
- Dim squad As SuperheroSquad = jsonSerializer.Deserialize(Of SuperheroSquad)(json)
- json = jsonSerializer.Serialize(json)
- End Sub
- End Class
- Public Class Member
- Public Property name As String
- Public Property age As Integer
- Public Property secretIdentity As String
- Public Property powers As String()
- End Class
- Public Class SuperheroSquad
- Public Property squadName As String
- Public Property homeTown As String
- Public Property formed As Integer
- Public Property secretBase As String
- Public Property active As Boolean
- Public Property members As Member()
- End Class
Auch hier gibt es die Möglichkeit, untypisiert zu arbeiten, hierauf werde ich aber nicht näher eingehen, da mir hier selbst die Erfahrung fehlt und ich die interne Implementierung nicht nutze. Falls Bedarf besteht, werde ich mich damit befassen.
Dieses Thema ist hier nicht erschöpft behandelt worden, jedoch sollte eine grundlegende Übersicht geschaffen worden sein, wie mit JSON-Daten gearbeitet werden kann. Sollten Fehler in meinen Ausführungen sein, so bitte ich um Korrektur. Ich bedanke mich fürs Lesen!
Danny!
Die Unendlichkeit ist weit. Vor allem gegen Ende.
Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken.
Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()