JSON mit .NET verarbeiten

JSON (Java Script Object Notation) wird für Webservices durch WCF häufig eingesetzt. Doch was verbirgt sich hinter JSON und wie kann man es selbst in .NET verarbeiten?

Die Hauptaufgabe von JSON ist es, ein kompaktes Datenformat, welches für Mensch wie auch Maschine einfach zu lesen ist, bereit zu stellen. JSON soll eine wesentlich schlankere Möglichkeit bietet, Daten zu verteilen. JSON wird oft für JavaScript Operationen und in AJAX-Anwendungen eingesetzt. JSON wird durch den MIME-Type “application/json” repräsentiert*. JSON-Objekte werden durch Klammern eingeleitet, deren Elemente sind in Hochkomma und die Werte je nach Typ entweder selbst in Hochkomma oder als Zahlenwert angegeben. Eine Person würde etwa folgenderweise aussehen:

{
“Name”:”Mario Meir-Huber”,
“Age”:2e+6,
}

Würde man dies in XML abbilden, so sieht dies (ohne Attribute) folgendermaßen aus:

<Person>
<Name>Mario Meir-Huber</Name>
<Age>27</Age>
</Person>

Das XML-Format hat 66 Zeichen, wohingegen für das JSON-Format lediglich 46 Zeichen anfallen. Selbst in einem sehr kleinen Objekt spart man somit Platz. Dies hat für Webservices natürlich gewisse Vorteile. JSON-Objekte kann man auch verschachteln:

{
“Name”:”Mario Meir-Huber”,
“Age”:2e+6,
“Address”:
{
“City”: “Vienna”
}
}

Werden Arrays abgebildet, so kommen diese in eckige Klammern: []. Innerhalb dieser Klammern werden die einzelnen Werte, welche wiederum verschachtelte Objekte sein können, zusammengesetzt.

{
“Name”:”Mario Meir-Huber”,
“Age”:2e+6,
“Address”:
{
“City”: “Vienna”
}
“Web”: [“www.codeforce.at”, “www.codefest.at”]
}

JSON Daten kann man in .NET über verschiedenste Libraries parsen. JSON.org nennt einige Projekte, welche JSON im .NEt Framework unterstützen. Ich selbst habe bereits ein Interop-Projekt mit Jayrock und eines mit Json.NET durchgeführt. Das für mich am besten geeignete Framework war Json.NET. Hierfür gibt es sogar eine LinQ to JSON Möglichkeit. Fangen wir jedoch mit der einfachsten Möglichkeit, deiner JSON Serialisierung, an. Im unten stehenden Beispiel erstellen wir ein Produkt, welches Unterprodukte haben kann. Dies rufen wir mit JSON.NET über “JsonConvert.SerializeObject” auf.

 Product p = new Product();
p.Name = "My powerfull Product";
p.Id = Guid.NewGuid();
p.ChildProduct = new Product();
p.ChildProduct.Name = "My child";
p.ChildProduct.Id = Guid.NewGuid();
p.ChildProduct.ChildProduct = new Product();
p.ChildProduct.ChildProduct.Name = "I am deep!";
p.ChildProduct.ChildProduct.Id = Guid.NewGuid();

string serialcontent = JsonConvert.SerializeObject(p);

Will man wieder die andere Richtung gehen, verwendet man “DeserializeObject”. In diesem Fall erstellen wir einfach nur eine Deep-Copy des Objektes.

 Product copy = JsonConvert.DeserializeObject<Product>(serialcontent);

Will man sich das serialisierte JSON Objekt ansehen, sieht dies folgendermaßen aus:

{
"Name": "My powerfull Product",
"Id":"01ed3cb1-2a99-4d62-bf1b-c878dbed6c9b",
"ChildProduct":
{
"Name":"My child",
"Id":"f48cbed8-ce83-4bcb-94f8-dbe10f26036a",
"ChildProduct":
{
"Name":"I am deep!",
"Id":"035b407e-4cec-4456-a47d-17df33b2f27a",
"ChildProduct":null,
"id":0,
"Date":"\/Date(-62135596800000+0100)\/"
},
"id":0,"Date":"\/Date(-62135596800000+0100)\/"
},
"id":0,"Date":"\/Date(-62135596800000+0100)\/"
}

LinQ to JSON funktioniert auch ganz einfach. Wir erstellen uns auch wieder ein Produkt, welches Serialisiert werden sollte. Wollen wir den Namen des Child-Produktes erfahren, greifen wir auf diesen dem Pfad zu:

 private static void DoSomeLinQToJson()
{
    Product p = new Product();
    p.Name = "My powerfull Product";
    p.Id = Guid.NewGuid();
    p.ChildProduct = new Product();
    p.ChildProduct.Name = "My child";
    p.ChildProduct.Id = Guid.NewGuid();
    p.ChildProduct.ChildProduct = new Product();
    p.ChildProduct.ChildProduct.Name = "I am deep!";
    p.ChildProduct.ChildProduct.Id = Guid.NewGuid();

    string serialcontent = JsonConvert.SerializeObject(p);

    JObject obj = JObject.Parse(serialcontent);

    var childName = (string)obj["ChildProduct"]["Name"];

    Console.WriteLine(childName);
}

Dies gibt uns dann den korrekten Produktnamen aus. Ob es sich dabei um richtiges LinQ handelt sei dahingestellt. Es besteht jedoch eine einfache Möglichkeit, Daten abzufragen. Sehr nett ist auch die Möglichkeit, dynamische Typen zu serialisieren:

 private static void WriteADynamicObject()
{
    dynamic obj = new ExpandoObject();

    obj.WhatEver = "Hello";
    obj.SomeThing = 123;

    Console.WriteLine(JsonConvert.SerializeObject(obj));
}

Im nächsten Beitrag werde ich JSON und XML etwas genauer vergleichen, wobei der Hauptteil auf einen Geschwindigkeits- wie auch Größenvergleich liegen soll.

Die Library findet Ihr unter https://json.codeplex.com/.

Mario Meir-Huber
Mail: mario.mh@codeforce.at
Twitter: www.twitter.com/mario_mh

*: https://tools.ietf.org/html/rfc4627