Title = "dotnetpro",
Year = 2013,
Number = 12,
PublicationDate = new DateTime(2013, 11, 21),
Articles = new List
{
new Article {
Title = "Kochen mit Patrick",
PageNumber = 123,
Authors = new List {
new Author {
FirstName = "Patrick A.",
LastName = "Lorenz"
}
}
}
}
}
};
Mit den weiter oben gezeigten Aufrufen produziert JSON.NET aus der Struktur ein ansehnliches Stück JSON:
[{
"Title": "dotnetpro",
"Year": 2013,
"Number": 12,
"PublicationDate": "2013-11-21T00:00:00",
"Articles": [
{
"Title": "Kochen mit Patrick",
"PageNumber": 123,
"Authors": [
{
"FirstName": "Patrick A.",
"LastName": "Lorenz"
}
]
}
]
}]
Offiziell unterstützt JSON keine Datumswerte. Hier spielt JSON.NET seine Stärken aus: Die Bibliothek bietet eine ausgesprochen umfangreiche Unterstützung von JSON mit sehr vielen Details und Spezialfällen. Datumswerte in verschiedenen gängigen Interpretationen gehören da schon zu den Basics.
Obwohl oder gerade weil man JSON und XML in manchen Anwendungsbereichen als Konkurrenten betrachten darf, bietet JSON.NET eine XML-Unterstützung. Diese erlaubt mit gewissen Einschränkungen die Konvertierung von JSON nach XML:
var issueJson =
JsonConvert.SerializeObject(
issues[0]);
var xml =
JsonConvert.DeserializeXmlNode(
issueJson, "issue");
Debug.WriteLine(xml.OuterXml);
Die Zeilen basieren auf dem vorherigen Beispiel und produzieren das folgende XML:
2013
12
2013-11-21T00:00:00
123
Patrick A.
Lorenz
Der Prozess lässt sich auch umkehren, allerdings mit Reibungsverlusten.
Im konkreten Beispiel geht die Abbildung der Unterstrukturen als Array verloren, im Vergleich zum JSON weiter oben fehlen die eckigen Klammern. Folglich lässt sich das rückermittelte JSON nicht mehr mit in das Ursprungsobjekt deserialisieren.
{ "Title": "dotnetpro",
"Year": "2013",
"Number“: "12",
"PublicationDate": "2013-11-21T00:00:0",
"Articles": {
"Title": "Kochen mit Patrick",
"PageNumber": "123",
"Authors": {
"FirstName": "Patrick A.",
"LastName": "Lorenz"
}
}
}
Für Faule wie mich: Code-Generierung
Zwar erlauben Bibliotheken wie JSON.NET den unstrukturierten Zugriff auf JSON-Daten mittels Dictionaries, wirklich interessant werden sie aber erst in Verbindung mit typisierten Klassen, die sich per Knopfdruck befüllen lassen. Wer mit einer externen Schnittstelle arbeitet, wird die dazu notwendigen Datenstrukturen in der Regel nicht vorliegen haben. Hier hilft der JSON C# Class Generator [2].
Das in Abbildung 1 gezeigte Programm besteht aus einem großen Eingabefeld und diversen Einstellungsmöglichkeiten. In das Feld wird ein möglichst aussagekräftiges Beispiel der zu verarbeitenden JSON-Struktur kopiert. Mit den Optionen lässt sich festlegen, ob die erzeugten Klassen Felder oder Eigenschaften verwenden sollen, welche Sichtbarkeit sie haben sollen, in welchem Namespace sie abgelegt werden und so weiter.

[Abb. 1] Der JSON C# Class Generator erzeugt aus einem JSON-Beispiel
eine passende Klassenstruktur.
Per Klick erzeugt das Programm eine passende Klassenstruktur entweder in C# oder Visual Basic. Die erkennbaren -Attribute gehören zu JSON.NET, das vom Programm explizit unterstützt wird. Sie dienen dem Mapping zwischen der JSON-Struktur und den Eigenschaften der Klasse. Im vorliegenden Fall ist das unnötig, lässt sich jedoch leider nicht abschalten.
namespace JSON.NET3 {
...
public class Issue {
[JsonProperty("Title")]
public string Title { get; set; }
[JsonProperty("Year")]
public int Year { get; set; }
[JsonProperty("Number")]
public int Number { get; set; }
[JsonProperty("PublicationDate")]
public string PublicationDate { get; set; }
[JsonProperty("Articles")]
public Article[] Articles { get; set; }
}
}
Als dritte Sprache neben C# und Visual Basic wird von JSON.NET übrigens TypeScript unterstützt:
module JSON.NET3 {
export interface Author {
FirstName: string;
LastName: string;
}
export interface Article {
Title: string;
PageNumber: number;
Authors: Author[];
}
export interface Issue {
Title: string;
Year: number;
Number: number;
PublicationDate: string;
Articles: Article[];
}
}
Als TypeScript-Fan finde ich das besonders spannend. Interessant ist das vor allem, um clientseitig aus TypeScript/ JavaScript typisiert auf ein externes API zugreifen zu können, im Zweifelsfall auch ganz ohne .NET. Für die kleine C#-Klasse zwischendurch gibt es unter [3] mit json2csharp eine Online-Version des Konverters (Abbildung 2).

[Abb. 2] C#-Datenstrukturen auf Knopfdruck.
In der Mehrzahl der Fälle liegen JSON-Strukturen nicht einfach so herum und warten darauf, deserialisiert zu werden. Meist wird JSON per HTTP mit REST-basierten Web-Diensten ausgetauscht – in beide Richtungen, versteht sich. JSON.NET konzentriert sich voll auf die Serialisierung und Deserialisierung. Der Datenaustausch gehört dagegen nicht zum Funktionsumfang. Der native Weg in .NET, Daten per HTTP abzufragen, führt über die -Klasse.
Das nachfolgende Beispiel zapft das Google Geocoding API [4] an und führt mit diesem eine Geo-Codierung für die recht unscharfe Adresse aus. Die Parametrisierung erfolgt über den Query-String. Der Web-Dienst liefert eine JSON-Struktur zurück, die mittels der gezeigten Funktionen von JSON.NET in ein zunächst untypisiertes Objekt deserialisiert werden kann.
using (var client = new WebClient()) {
client.Encoding = System.Text.Encoding.UTF8;
const string url = "http://maps.googleapis.com/maps/api/ geocode/json? address=Freiburg&sensor=false";
var jsonStr = client.DownloadString(url);
var result =
JsonConvert.DeserializeObject( jsonStr);
Debug.WriteLine(result);
}
Zwar funktioniert dieser Ansatz, als sonderlich komfortabel muss man ihn aber nicht bezeichnen. Alternativ gibt es diverse Bibliotheken und Erweiterungen, die auf JSON.NET aufbauen und dessen Funktionsumfang um eine HTTP-Kommunikationsschicht ergänzen. RestSharp [5] ist eine davon – oder vielmehr war es. Die Bibliothek kapselt den Zugriff auf REST-basierte Web-Dienste und erlaubt dem .NET-Entwickler deren komfortable Bedienung. Als Datenformate werden XML und JSON unterstützt.
Die Einbindung in Ihr Projekt erfolgt wie gewohnt per NuGet:
PM> Install-Package RestSharp
Die Bibliothek konzentriert sich auf drei Strukturen. konfiguriert einen Endpunkt. Mit werden einzelne Abfragen zusammengestellt. Deren Ergebnis wird als zurückgeliefert.
Die folgenden Zeilen führen die identische Abfrage mit dem Google Geocoding API durch:
var client = new RestClient {
BaseUrl = "http://maps.googleapis.com"
};
var request = new RestRequest( "maps/api/geocode/json");
request.AddParameter( "address", "Freiburg");
request.AddParameter( "sensor", "false");
var result = client.Execute(request);
Debug.WriteLine(result.Content);
Im Beispiel ist sehr schön zu erkennen, wie sauber sich Abfragen mit RestSharp strukturieren und mittels Parametern qualifizieren lassen.
Читать дальше