RSS FeedFeed TwitterTwitter XINGXING
  
Meine Bücher

Erscheint demnächst: Verteilte Systeme und Services mit .NET 4.5: Konzepte und Lösungen für WCF 4.5 und ASP.NET Web-API ,
Hanser Fachbuchverlag

Weitere Infos

 

.NET 4.5 Update,
Microsoft Press

Weitere Infos

 

Verteilte Systeme und Services mit .NET 4.0: Konzepte und Lösungen mit WCF 4.0,
Hanser Fachbuchverlag

Weitere Infos

 
Weitere Bücher
Meine Artikel

Leichtgewichtige Kommunikation: REST-basierte Services mit dem neuen API aus der ASP.NET-Familie,
windows.developer

Weitere Infos

 

Windows Azure Tutorial, Teil 3: Verbindung zwischen Cloud- und lokalen Applikationen,
iX - Magazin für professionelle Informationstechnik

Weitere Infos

 

Weitere Artikel

Schulung & Beratung

Gemeinsam mit meinen Kollegen aus dem IT-Visions Netzwerk unterstützte ich durch zielgerichtete Inhouse-Trainings und Consulting Unternehmen bei der Planung und Umsetzung großer Software-Systeme mit der Microsoft/.NET-Plattform.

 
Konferenzen

Scandinavian Developer Conference 2013 (SDC 2013) von 04.03.2013 bis 06.03.2013 in Göteborg

Meine Talks

Web-Site der Konferenz

 

BASTA! on Tour Spring 2013 von 24.04.2013 bis 26.04.2013 in Düsseldorf

Meine Talks

Web-Site der Konferenz

 

5th SOA and Cloud-Technology Symposium 2012 von 24.09.2012 bis 25.09.2012 in London

Meine Talks

Web-Site der Konferenz

 
Weitere Konferenzen
von Manfred, 13. Dezember 2011 00:00

Für den Zugriff auf REST-basierte Services bietet WCF WebAPI mit der Klasse HttpClient eine Erleichterung für Entwickler. In den Genuss dieser Neuerung kommt man, indem man über NuGet die WebAPI ins Client-Projekt lädt.

Asynchronität

WebClient ist in Hinblick auf Asynchronität  entworfen, was man unter anderem daran bemerkt, dass sämtliche Methoden, welche zum Übertragen von Daten zur Verfügung stehen, lediglich in einer aynchronen Variante, welche als Ergebnis einen Task liefert, angeboten werden. Über die Eigenschaft Result von Task kommt man dann zum Ergebnis, wobei diese Eigenschaft so lange blockiert, bis dieses tatsächlich zur Verfügung steht. Dies korreliert mit dem Mindset, welches mit Windows 8 und Metro Einzug halten soll: Alles was länger als x ms dauert, wird zur Verbesserung des Antwortverhaltens der Anwendung asynchron.

Anfragen absenden

Für die vier populärsten HTTP Verben steht jeweils eine Methode zur Verfügung: GetAsync, PostAsync, PutAsync und DeleteAsync. Übergeben wird an diese Methoden die URL der anzusprechenden Ressource. Überladungen erlauben auch die Übergabe eines CancellationTokens zum Abbruch der angestoßenen asynchronen Aktion sowie das Angeben eines Wertes des enums HttpCompletionOption. Mit letzterem wird festgelegt, ob lediglich der Header (HttpCompletionOption.ResponseHeadersRead) oder auch die Nutzdaten (HttpCompletionOption.ResponseContentRead) der Antwort zu lesen sind.

 

Daten senden

 

Der Einsatz von PostAsync und PutAsync erwartet die Übergabe von zu sendenden Nutzdaten in der Form einer Instanz des Typs HttpContent (siehe Methode PostBuchungDemo, unten). Hierbei handelt es sich um eine abstrakte Klasse, deren Subklassen verschiedene Darstellungsformen von Ressourcen repräsentieren. So kann zum Beispiel an ObjectContent, wie in der unten abgebildeten Methode PostBuchungDemo ersichtlich, ein zu serialisierendes Objekt übergeben werden. Alternativen dazu sind u. a. die selbstsprechenden Klassen StringContent und StreamContent. Hierbei ist darauf zu achten, dass jene HTTP-Header, die den Inhalt betreffen dem ObjectContent bekannt zu geben sind; die restlichen können über die Eigenschaft DefaultRequestHeaders von HttpClient festgelegt werden. Wie der Name dieser Eigenschaft schon vermuten lässt, werden diese Header-Einträge standardmäßig bei jedem Aufruf, der über den jeweiligen HttpClient erfolgt, herangezogen. Diese logische Aufteilung dürfte für HTTP-Kenner nicht gerade intuitiv erscheinen, da sämtliche HTTP-Header gemeinsam und ohne Gruppierung übertragen werden.

 

Die volle Kontrolle

 

Möchte man die volle Kontrolle über die zu sendenden Anfragen haben, kann die Methode SendAsync bemüht werden (siehe Methode SendBuchungDemo, unten). In diesem Fall kann man von den vier Verben GET, POST, PUT und DELETE abweichen und auch Header-Einträge für eine bestimmte Anfrage setzen.

Fazit

Auch wenn die betrachtete API derzeit noch ein wenig Wortreich ist und ab und an ein paar Convenience-Methoden schön wären, bietet diese sich noch in Entwicklung befindliche API mehr Komfort als die bis dato zur Verfügung gestandenen Alternativen. Man muss sich nicht mehr um das Serialisieren und Deserialisieren selber kümmern, es werden out-of-the-box die wichtigsten Darstellungsformen, wie JSON, XML oder URL-Encodet Strings, unterstützt und man erhält Unterstützung beim Definieren der Header durch die API.

private static void GetHotelsDemo()
{
    HttpClient client = new HttpClient();

    HttpResponseMessage response = client
                                    .GetAsync("http://localhost:5721/hotels?$filter=Sterne ge 4",HttpCompletionOption.ResponseContentRead)
                                    .Result;
            
    if (!response.IsSuccessStatusCode)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Fehler: " + response.StatusCode + " "
                            + response.Content.ReadAsStringAsync().Result);
        Console.ReadLine();
    }

    var hotels = response
                    .Content
                    .ReadAsOrDefaultAsync<List<Hotel>>()
                    .Result;

    foreach (var hotel in hotels)
    {
        Console.WriteLine(hotel.ToString());
    }
}

private static void PostBuchungDemo()
{
    HttpClient client = new HttpClient();

    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("bar"));
    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("x-styrian"));
    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("de"));

    HotelBuchung buchung = new HotelBuchung { HotelId = 2, Vorname = "Peter", Nachname="Silie" };
    HttpContent content = new ObjectContent(typeof(HotelBuchung), buchung);
    content.Headers.ContentType = JsonMediaTypeFormatter.DefaultMediaType;
            
    HttpResponseMessage response = client
                                    .PostAsync("http://localhost:5721/hotels/3/buchungen", content)
                                    .Result;

    if (!response.IsSuccessStatusCode)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Fehler: " + response.StatusCode + " "
                            + response.Content.ReadAsStringAsync().Result);
        Console.ReadLine();
    }

    Console.WriteLine("Status: " + response.StatusCode);
    Console.WriteLine("Content: " + response.Content.ReadAsStringAsync().Result);

}

private static void SendBuchungDemo()
{
    HttpClient client = new HttpClient();

    HotelBuchung buchung = new HotelBuchung { HotelId = 2, Vorname = "Peter", Nachname = "Silie" };

    HttpContent content = new ObjectContent(typeof(HotelBuchung), buchung);
    content.Headers.ContentType = JsonMediaTypeFormatter.DefaultMediaType;

    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:5721/hotels/3/buchungen");
    request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("bar"));
    request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("x-styrian"));
    request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("de"));
    request.Content = content;

    HttpResponseMessage response = client
                                    .SendAsync(request)
                                    .Result;

    if (!response.IsSuccessStatusCode)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Fehler: " + response.StatusCode + " "
                            + response.Content.ReadAsStringAsync().Result);
        Console.ReadLine();
    }

    Console.WriteLine("Status: " + response.StatusCode);
    Console.WriteLine("Content: " + response.Content.ReadAsStringAsync().Result);

}

Kategorien: Services | WCF