ASP.NET Web API – Leichtgewichtiger WebService

27. Februar 2013
Wie in meinem letzten Beitrag angekündigt habe, gehe ich heute auf die ASP.NET Web API ein. In meinem letzten Beitrag habe ich die ASP.NET Web API dazu genutzt, um Daten über einen gemeinsamen Service in einer Webanwendung und einer Metroanwendung anzuzeigen und zu verarbeiten.

Entsprungen sind die ASP.NET Web API aus den WCF Web APIs, einem Projekt auf CodePlex. Die ASP.NET Web API erleichtert es auf Basis der .NET Technologie HTTP Services zu erstellen, die eine breite Masse an Endgeräten/Empfängern erreichen. ASP.NET Web API ist damit eine ideale Plattform um RESTful Anwendungen mit dem .NET Framework zu erstellen.

Der Nutzen an der ganze Sache ist der, dass alles über HTTP läuft und es damit auf quasi jeder Plattform genutzt werden kann. Ganz egal auf welchem OS wir uns befinden, man kann eigentlich immer sicher sein, dass es dort die Möglichkeit gibt per HTTP zu kommunizieren.

HTTP bietet ein Reihe von Request Methoden, um Ressourcen (z.B. Webseiten,Daten) anzufordern oder zu versenden. Im folgenden werde ich die Methoden, die für die ASP.NET Web API von Bedeutung sind auflisten und kurz beschreiben:

GET: fordert Ressource an
POST: sendet Daten an Server. Dies geschieht meist in Form von Name-Wert-Paaren aus HTML-Formularen.
PUT: wird genutzt, um Dateien auf einen Server hochzuladen.
DELETE: wird genutzt, um eine Ressource zu löschen.

Diese Methoden werden in den ASP.NET Web API Controllern abgebildet. Ein Beispiel Controller für die Übersicht der Bilanzdaten ist im folgenden abgebildet:

   1: public class OverviewController : ApiController

   2:     {

   3:         // GET api/overview

   4:         public IEnumerable<Overview> Get()

   5:         {

   6:             return new Overview[] { new Overview(){Name = "laufende Bilanz", Bemerkung = "Bilanzdaten zur laufenden Bilanz" }, new Overview() {Name = "letzte Bilanz"} };

   7:         }

   8:  

   9:         // GET api/overview/5

  10:         public Overview Get(int id)

  11:         {

  12:             return new Overview(){Name = "laufende Bilanz", Bemerkung = "Bilanzdaten zur laufenden Bilanz" };

  13:         }

  14:  

  15:         // POST api/overview

  16:         public void Post([FromBody]string value)

  17:         {

  18:         }

  19:  

  20:         // PUT api/overview/5

  21:         public void Put(int id, [FromBody]string value)

  22:         {

  23:         }

  24:  

  25:         // DELETE api/overview/5

  26:         public void Delete(int id)

  27:         {

  28:         }

  29:     }

Um also jetzt mit den Funktionen des Controllers zu kommunizieren ruft man einfach folgende URL auf:

http://localhost:port/api/overview

Gibt man diese URL in den Browser ein, wird per Default vom Browser die GET Methode genutzt. Was wird aber nun im Browser angezeigt? Schließlich gibt die Funktion, die für die GET Methode zuständig ist, ein IEnumerable<Overview> zurück. Der Browser kann damit nur leider nichts anfangen. Blöd!

Aber keine Panik, hier hilft uns die ASP.NET Web API und serialisiert einfach automatisch alle .NET Objekte.

Okay, es serialisiert, cool … aber in was serialisiert es denn?

Hier kommt ein weiteres Highlight der ASP.NET Web API: Es serialisiert entweder in XML oder in JSON. Es kommt ganz darauf an, was man anfordert.

Gibt man im Browser die URL ein, wird per Default der Accept-Header auf “text/html,application/xhtml+xml,application/xml” gesetzt und man bekommt XML zurück. Will man die Daten aber lieber in JSON haben, gibt man im Accept-Header einfach application/json, text/javascript an.

Die Serialisierung der Daten nach XML oder JSON kommt also frei Haus. Ich finde es sau cool!

Beispiel – JavaScript und jQuery

Beispiel für einen GET-Request:

   1: $.getJSON("api/overview/", function (data) {

   2:     // Beim Erfolg enthält data eine Liste/Array von Overviews.

   3:     // Die Daten sind hier im JSON Format zurückgekommen.

   4:     $.each(data, function (key, val) {

   5:         // Eintrag zur Liste Hinzufügen. #overview ist ein <ul>.

   6:         $('<li/>', { text: val.Name + ", " + val.Bemerkung })    

   7:         .appendTo($('#overview'));   

   8:     });

   9: });

Es wird per $.getJSON ein GET-Request ausgeführt. Dieser wird von unserer RESTful Funktion im Controller entgegen genommen, die ein IEnumerable<Overview> zurückgibt. Als Ergebnis liefert diese Funktion die Daten im JSON Format, weil per $.getJSON der Accept Header auf application/json gesetzt wird.

Beispiel für einen POST-Request:

   1: //Im Client

   2:  

   3: var json = JSON.stringify(neueÜbersicht);

   4: $.ajax("api/overview",{

   5:     type: 'POST',

   6:     data: json,

   7:     contentType: 'application/json; charset=utf-8',

   8:     statusCode: {

   9:         201 /*Created*/: function(data){

  10:             // Data ist das hinzugefügte Übersichtsobjekt.

  11:             // Dieses kann jetzt verwendet werden und z.B.

  12:             // einer Liste hinzugefügt werden:

  13:             // viewModel.overviews.push(data);

  14:         }

  15:     }

  16: });

  17:  

  18: // Im Controller

  19:  

  20: // POST api/overview

  21: public HttpResponseMessage Post(Overview overview)

  22: {

  23:     Overview posten = this.overviewbl.Create(overview);

  24:     var response = Request.CreateResponse(HttpStatusCode.Created, overview); //Created = 201

  25:     var uri = Url.Link("DefaultApi", new { id = overview.ID });

  26:     response.Headers.Location = new Uri(uri);

  27:  

  28:     return response;

  29: }

Hier legen wir eine neue Übersicht an. Auf der Client Seite wir ein neues Overview-Objekt erstellt, dieses wird dann per $.ajax an den Controller übertragen und dort von unserer overviewbl persistiert. Das erzeugte Objekt wird im Response zurückgegeben und kann dann im Client weiterverarbeitet werden.

Beispiel – C#

Für das nächste Beispiel lädt man sich am besten das NuGet Package ASP.NET Web API Client Libraries herunter. Dieses ermöglicht einen einfachen Umgang mit der Web API auf Client Seite mit .NET.

Beispiel für einen GET-Request in einer Konsolenanwendung:

   1: HttpClient client = new HttpClient(clientHandler);

   2: client.BaseAddress = new Uri("http://localhost:63742/");

   3:  

   4: // Will man JSON zurückbekommen, muss man ihm das sagen

   5: client.DefaultRequestHeaders.Accept.Add(

   6:     new MediaTypeWithQualityHeaderValue("application/json"));

   7:  

   8: HttpResponseMessage response = client.GetAsync("api/overview").Result;  // Ab hier warten!

   9: if (response.IsSuccessStatusCode)

  10: {

  11:     var overviews = response.Content.ReadAsAsync<IEnumerable<Overview>>().Result; // Auch hier wieder warten!

  12:     foreach (var o in overviews)

  13:     {

  14:         Console.WriteLine("{0}	{1}", o.Name, o.Bemerkung);

  15:     }

  16: }

  17: else

  18: {

  19:     Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);

  20: }

Hier passiert eigentlich dasselbe, wie in dem jQuery-Beispiel. Zunächst wird die URL des Controllers angegeben. Dann überlegt man sich, wie die Daten zurückkommen sollen. Anschließend führen wir einen GET-Request aus. Als Ergebnis bekommen wir eine Liste von Overview-Objekten. Für die Deserialisierung muss auf dem Client eine Overview-Klasse mit den Eigenschaften existieren, die für einen interessant sind. Soll heißen, es muss nicht die “gleiche” Klasse abgebildet werden.

Beispiel für einen POST-Request:

   1: var overview = new Overview() { Name = "Voll", Bemerkung = "Abgefahren" };

   2: Uri newOverviewUri = null;

   3:  

   4: response = client.PostAsJsonAsync("api/overview", overview).Result;

   5: if (response.IsSuccessStatusCode)

   6: {

   7:     newOverviewUri = response.Headers.Location;

   8:     Console.WriteLine(newOverviewUri);

   9: }

  10: else

  11: {

  12:     Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);

  13: }

Auch hier passiert dasselbe, wie in dem jQuery Beispiel. Zunächst erzeugt man ein neues Overview-Objekt und übermittelt es zum Abspeichern an den Server. Dort wird es persistiert und als Ergebnis bekommt man es wieder zurück um es weiter zu verarbeiten.

Beispiel – alles andere

Beispiele für andere Sprachen schenke ich mir an dieser Stelle mal. Ich denke das Konsumieren der ASP.NET Web API ist klar geworden 🙂

Fazit

Die ASP.NET Web API ist ein weiterer Schritt hin zu einem flexibleren Web. Der Trend geht weg von der serverseitigen Erstellung von Webcontent hin zu flexiblen und leichtgewichtigen Lösungen aus JavaScript und Template Frameworks zum Erzeugen der UI. Mit den ASP.NET Web API haben Sie eine Technik im Hintergrund, die dafür bestens ausgelegt ist!

Ich hoffe es ist deutlich geworden, wie man einfach und schnell einen RESTful WebService mithilfe der ASP.NET Web API entwickelt und damit sämtliche Clients mit Daten füttern kann.