Читать книгу Kochen mit Patrick - Patrick A. Lorenz - Страница 10

Was JSON.NET nicht kann

Оглавление

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.

Die JSON-Rückmeldung des Web-Dienstes wird von als Zeichenkette geliefert und testweise im Output-Fenster ausgegeben.

Freiburg wird natürlich gefunden und Google spendiert unter anderem passende Geo-Koordinaten:

...

"formatted_address" : "Freiburg, Germany",

"geometry" : {

"location" : {

"lat" : 47.9990077,

"lng" : 7.842104299999999

},

...

Statt als String kann das Ergebnis ähnlich wie bei JSON.NET in eine .NET-Klassenstruktur deserialisiert werden:

...

var result = client.Execute<GeoResult>(request);

foreach (var geoResult in result.Data.results) {

Debug.WriteLine( geoResult.formattedAddress);

Debug.WriteLine("Lat: {0}, Lng: {1}", geoResult.geometry.location.lat,

geoResult.geometry.location.lng

);

}

Die notwendige Klassenstruktur habe ich im Vorfeld manuell angelegt. Sie muss recht engen Vorgaben genügen, ansonsten scheitert die Deserialisierung und die Komponente liefert schlicht .

Früher hat an dieser Stelle JSON.NET intern seinen Dienst verrichtet. Dies hat der RestSharp-Entwickler in den jüngsten Versionen jedoch zugunsten einer Eigenentwicklung aufgegeben. Wer lieber mit JSON.NET arbeitet, kann dessen Unterstützung mit wenigen Zeilen integrieren. Dazu bedarf es eines eigenen Deserialisierers als Brücke zwischen RestSharp und JSON.NET:

public class JsonDeserializer : IDeserializer

{

public JsonDeserializer() {

this.ContentType = "application/json";

}

public string RootElement { get; set; }

public string Namespace { get; set; }

public string ContentType { get; set; }

public string DateFormat { get; set; }

public T Deserialize<T>(

IRestResponse response) {

// Deserialisierung mit JSON.NET

return JsonConvert.

DeserializeObject<T>( response.Content);

}

}

Die Klasse wird gegenüber RestSharp als Handler registriert, und schon arbeiten beide Komponenten wieder Hand in Hand:

var client = new RestClient {

BaseUrl = "http://maps.googleapis.com"

};

client.AddHandler("application/json",

new JsonDeserializer());

Kochen mit Patrick

Подняться наверх