ASP.NET MVC 4 – WebAPI

written by devangelist on Oktober 25, 2012 in Allgemein and API and ASP.NET and ASP.NET MVC and ASP.NET MVC Web API and Javascript and jQuery and JSON with 7 comments

Die wohl am wertvollste Neuerung für die vierte Version des beliebten MVC Frameworks ist die Web API.

Die Web API ist im Grunde ein Framework welches die Kommunikation zwischen Client und Server vereinfachen soll. Praktisch ausgedrückt werden auf der Seite des Servers die HTTP Services zur Verfügung gestellt und beispielsweise auf dem Client über Javascript/jQuery konsumiert. Mittlerweile hat sich als Austauschformat JSON, unter anderem aufgrund der reduzierten Größe im Verhältnis zu XML zum breiten Standard entwickelt. Insbesondere dann, wenn die Kommunikation von Client zu Server und nicht von Server zu Server stattfindet.

Warum Web API?

Eine Rückgabe in JSON und XML sowie einen Status-Code - genau das soll eine API können und genau das kann die Web API besonders gut.

Interessant sind unter anderem die aus MVC bekannten Features wie die komplette Unterstützung von Routes sowie Filter-Attribute, wie das [Authorize]-Attribut.

Dazu eine bessere Testbarkeit, verbessertes Inversion of Control (IoC) via DependencyResolver, code-basierte Konfigurationsmöglichkeiten, etc.

Bekanntlich werden bei einem Beispiel die Begriffe, welche in theoretischer Hinsicht attraktiv klingen, auch in der Praxis schmackhaft gemacht.

Schritt 1) Das Model

Das Model ist nichts anderes als ein Objekt welches die Daten in der Anwendung darstellt. Die ASP.NET Web API kann dieses automatisch zu JSON und XML serialisieren, je nach dem welches Format im Accept-header des HTTP Requests mitgesendet wurde. Keine Sorge, dies wird im Normalfall von jQuery übernommen.

Dafür im Solution Explorer eine neue Klasse Person im Ordner Models erstellen:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Schritt 2) Die Datenquelle / Repository

Für das Beispiel wird aus Einfachheit eine Generische Liste verwendet, in real-world Anwendung wird dies mit einem richtigen Repository und einer Datenquelle wie zum Beispiel dem Entity Framework ausgetauscht.

private IList _repository = new List();

Schritt 3) Der Web API Controller

Wer bereits mit ASP.NET MVC gearbeitet hat, kennt das Prinzip der Controller. Im Grunde nichts anderes als Klassen, welche die HTTP-Requests handhaben und die Logik beinhalten, sprich die Schnittstelle zwischen Data und View.

Dafür wieder in den Solution Explorer wechseln und im Controller-Ordner einen neuen Controller “PersonController” hinzufügen. Als Template-Einstellung “Empty API Controller“.

Der Controller soll am Ende die komplette CRUD-Palette (Create, Read, Update, Delete) abdecken, somit die Methoden Get, GetAll, Post, Put und Delete beinhalten.

1) Get/Read

Der Read-Request dient zum Auslesen von einem oder von allen Datensätzen:

public IEnumerable GetAll()
{
    return _repository.ToList();
}

public Person Get(int id)
{
    var person = _repository.FirstOrDefault(p => p.Id == id);
    if (person == null)
    {
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }
    return person;
}

Neu ist die in Zeile 11 gezeigte HttpResponseException, welche dem Client eine Antwort mit einem 404-Statuscode (not found) zurückgibt.

Den Aufruf dieser Funktionen übernimmt ein einfaches jQuery get:

function getPersons() {
    $.ajax({
        url: "/api/Person",
        type: "GET",
        contentType: "application/json;charset=utf-8",
        statusCode: {
            200: function (persons) {
                $.each(persons, function(key, person) {
                    // person.Name ...
                });
            }
        }
    });
}

function getPerson(id) {
    $.ajax({
        url: "/api/Person",
        data: { id: id },
        type: "GET",
        contentType: "application/json;charset=utf-8",
        statusCode: {
            200: function (person) {
                alert(person.Name);
            },
            404: function () {
                alert("Nicht gefunden!");
            }
        }
    });
}

2) Post/Create

Das Erstellen von neuen Objekten wird konform mit einem HTTP-Post Request ausgeführt. Dafür eine Funktion erstellen welche mit “Post..” beginnt.

Zu beachten gilt:

  • Bei erfolgreicher Transaktion wird der Status-Code 200 (OK) zurückgegeben. Laut dem HTTP/1.1 Protokoll muss allerdings nach einem erfolgreichen Erstellen der Status-Code 201 (Created) zurückgegeben werden.
  • Wenn der Server eine neue Ressource erstellt hat, sollte im Location-Header die URI der erstellten Ressource mitgegeben werden.

Die Web API bietet eine HttpResponseMessage-Klasse, mit welcher die eben genannten Voraussetzungen zum Kinderspiel werden:

public HttpResponseMessage PostPerson(Person person)
{
    _repository.add(person);
    var response = Request.CreateResponse(HttpStatusCode.Created, person);
    var uri = Url.Route(null, new { id = person.Id });
    response.Headers.Location = new Uri(Request.RequestUri, uri);
    return response;
}
function createPerson(person) {
    $.ajax({
        url: "/api/Person",
        data: JSON.stringify(person),
        type: "POST",
        contentType: "application/json;charset=utf-8",
        statusCode: {
            201: function (newPerson) {
                alert("Person erstellt: " + newPerson.Name);
            }
        }
    });
}

3) Put/Update

Selbe Vorgehensweise wie im Create, anstatt Post wird Put verwendet:

public void PutPerson(int id, Person person)
{
    var personToUpdate = _repository.FirstOrDefault(p => p.Id == id);
    if (personToUpdate == null)
    {
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }
    personToUpdate.Name = person.Name;
    // ...
}
function updatePerson(person) {
    $.ajax({
        url: "/api/Person",
        data: JSON.stringify(person),
        type: "PUT",
        contentType: "application/json;charset=utf-8",
        statusCode: {
            200: function () {
                // OK
            },
            404: function () {
                alert("Person nicht gefunden!");
            }
        }
    });
}

Die Put-Methode nimmt zwei Parameter entgegen: eine Id des zu aktualisierenden Objekts und das Objekt selbst.

4) Delete

Die Funktion fängt mit “Delete…” an und nimmt die id des zu löschenden Objekts als Parameter entgegen:

public HttpResponseMessage DeletePerson(int id)
{
    var personToDelete = _repository.FirstOrDefault(p => p.Id == id);
    _repository.Remove(personToDelete);
    return new HttpResponseMessage(HttpStatusCode.NoContent);
}
function deletePerson(id) {
    $.ajax({
        url: "/api/Person",
        data: JSON.stringify({ id: id }),
        type: "DELETE",
        contentType: "application/json;charset=utf-8",
        statusCode: {
            204: function () {

            }
        }
    });
}

Um der HTTP-Spezifizierung gerecht zu bleiben können bei mehreren gleichzeitigen Delete-Requests unterschiedliche Antworten zurückkommen:

  • Wenn das Löschen erfolgreich war, ein Status 200 (OK).
  • Wenn das Löschen im Gange ist, ein 202 (Accepted).
  • Alternativ 204 (No Content).

Fazit

Durch die Einführung dieses Frameworks wird deutlich in welche Richtung sich Microsoft entwickelt – die Web API kann als eine wirklich Moderne, solide Basis für Web-Anwendungen dienen und schließt damit die Lücke von MVC 3 zu einem wirklich brauchbarem Werkzeug.

Weitere Neuerungen wie die Validierung der Eingabe, welche bereits in früheren Versionen des MVC-Frameworks oft durch Data-Annotations-Attribute gelöst wurde, wird ebenfalls von der Web API unterstützt. Dazu mehr im nächsten Post!

ASP.NET MVC 4 – WebAPI: 1 Stern2 Sterne3 Sterne4 Sterne5 Sterne 4,33 von 5 Punkte, 9 abgegebene Stimmen.
Loading ... Loading ...

About the Author

Roberto Bez ist passionierter Webentwickler und TechLead bei der HolidayCheck AG. Für Roberto bedeutet das Entwickeln nicht nur Arbeit, sondern auch Freude, Motivation und täglich neue, aufregende Herausforderungen. Besonders gerne setzt er sich mit neuen Webtechnologien sowie Datenbanken aller Art auseinander und versucht diese in die tägliche Anwendungsentwicklung miteinzubringen. Neben dem Entwickeln trifft man ihn gerne Abends beim Laufen oder im Sommer bei Mountainbike-Touren durch die schönen Berge Südtirols.