webentwicklung-frage-antwort-db.com.de

Warum sollte ich IHttpActionResult anstelle von HttpResponseMessage verwenden?

Ich habe mit WebApi entwickelt und bin zu WebApi2 übergegangen, wo Microsoft eine neue IHttpActionResult -Oberfläche eingeführt hat, die anscheinend für die Rückgabe einer HttpResponseMessage empfohlen wird. Ich bin verwirrt über die Vorteile dieser neuen Schnittstelle. Es scheint hauptsächlich nur eine GERINGFÜGIG einfachere Möglichkeit zu bieten, ein HttpResponseMessage zu erstellen.

Ich würde argumentieren, dass dies "Abstraktion der Abstraktion zuliebe" ist. Vermisse ich etwas? Was sind die realen Vorteile, die ich durch die Verwendung dieses neuen Interfaces erhalte, abgesehen davon, dass ich möglicherweise eine Codezeile speichere?

alter Weg (WebApi):

public HttpResponseMessage Delete(int id)
{
    var status = _Repository.DeleteCustomer(id);
    if (status)
    {
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    else
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}

New Way (WebApi2):

public IHttpActionResult Delete(int id)
{
    var status = _Repository.DeleteCustomer(id);
    if (status)
    {
        //return new HttpResponseMessage(HttpStatusCode.OK);
        return Ok();
    }
    else
    {
        //throw new HttpResponseException(HttpStatusCode.NotFound);
        return NotFound();
    }
}
302
Jason Roell

Möglicherweise möchten Sie IHttpActionResult nicht verwenden, da Ihr vorhandener Code ein HttpResponseMessage erstellt, das nicht zu einer der vordefinierten Antworten passt. Sie können jedoch HttpResponseMessage an IHttpActionResult anpassen, indem Sie die vordefinierte Antwort von ResponseMessage verwenden. Es hat eine Weile gedauert, bis ich das herausgefunden habe, und ich wollte zeigen, dass Sie sich nicht unbedingt für das eine oder andere entscheiden müssen:

public IHttpActionResult SomeAction()
{
   IHttpActionResult response;
   //we want a 303 with the ability to set location
   HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.RedirectMethod);
   responseMsg.Headers.Location = new Uri("http://customLocation.blah");
   response = ResponseMessage(responseMsg);
   return response;
}

Beachten Sie, dass ResponseMessage eine Methode der Basisklasse ApiController ist, von der Ihr Controller erben soll.

287
AaronLS

Sie können weiterhin HttpResponseMessage verwenden. Diese Fähigkeit wird nicht verschwinden. Ich habe das Gleiche wie Sie empfunden und mich ausführlich mit dem Team auseinandergesetzt, dass es keiner zusätzlichen Abstraktion bedarf. Es gab ein paar Argumente, um seine Existenz zu rechtfertigen, aber nichts, was mich davon überzeugt hätte, dass es sich lohnt.

Das heißt, bis ich diese Probe von Brad Wilson sah. Wenn Sie IHttpActionResult Klassen in einer Weise erstellen, die verkettet werden kann, können Sie eine Antwort-Pipeline auf "Aktionsebene" für erstellen Erzeugen des HttpResponseMessage. Dies ist die Art und Weise, wie ActionFilters implementiert wird. Die Reihenfolge dieser ActionFilters ist jedoch nicht offensichtlich, wenn ich die Aktionsmethode lese. Dies ist ein Grund, warum ich kein Fan von Aktionsfiltern bin.

Indem Sie jedoch ein IHttpActionResult erstellen, das in Ihrer Aktionsmethode explizit verkettet werden kann, können Sie alle Arten von Verhalten erstellen, um Ihre Antwort zu generieren.

83
Darrel Miller

Hier sind einige Vorteile von IHttpActionResult gegenüber HttpResponseMessage, die in Microsoft ASP.Net Documentation erwähnt werden:

  • Vereinfacht das Testen Ihrer Steuerungen.
  • Verschiebt die allgemeine Logik zum Erstellen von HTTP-Antworten in separate Klassen.
  • Verdeutlicht die Absicht der Controller-Aktion, indem die Details der Erstellung der Antwort ausgeblendet werden.

Aber hier sind einige andere Vorteile der Verwendung von IHttpActionResult, die es wert sind, erwähnt zu werden:

  • Beachtung des Grundsatzes der einfachen Verantwortung : Verursacht, dass Aktionsmethoden die Verantwortung dafür tragen, die HTTP-Anforderungen zu bedienen, und bezieht sie nicht in die Erstellung der HTTP-Antwortnachrichten ein.
  • Nützliche Implementierungen , die bereits in System.Web.Http.Results definiert sind, nämlich: OkNotFoundExceptionUnauthorizedBadRequestConflictRedirectInvalidModelState ( Link zur vollständigen Liste )
  • Verwendet standardmäßig Async und Await .
  • Einfach zu erstellendes ActionResult durch Implementierung der Methode ExecuteAsync.
  • sie können ResponseMessageResult ResponseMessage(HttpResponseMessage response) verwenden, um HttpResponseMessage in IHttpActionResult zu konvertieren.
59
// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage); 
32
Adam Tal

Dies ist nur meine persönliche Meinung und Leute vom Web-API-Team können es wahrscheinlich besser ausdrücken, aber hier ist meine 2c.

Zunächst denke ich, dass es sich nicht um eine Frage der anderen handelt. Sie können sie beide verwenden, je nachdem, was Sie in Ihrer Aktionsmethode tun möchten. Um jedoch die wahre Kraft von IHttpActionResult zu verstehen, müssen Sie wahrscheinlich die praktischen Hilfsmethoden von ApiController verlassen, z Ok, NotFound usw.

Grundsätzlich denke ich, dass eine Klasse IHttpActionResult als eine Factory von HttpResponseMessage implementiert. Mit dieser Einstellung wird es nun zu einem Objekt, das zurückgegeben werden muss, und zu einer Fabrik, die es produziert. Im allgemeinen Sinn der Programmierung können Sie das Objekt in bestimmten Fällen selbst erstellen, und in bestimmten Fällen benötigen Sie eine Factory, um dies zu tun. Hier gilt das gleiche.

Wenn Sie eine Antwort zurückgeben möchten, die durch eine komplexe Logik erstellt werden muss, z. B. viele Antwortheader usw., können Sie all diese Logik in eine Aktionsergebnisklasse abstrahieren, die IHttpActionResult implementiert, und sie in mehreren Aktionsmethoden verwenden, um Antwort zurück.

Ein weiterer Vorteil der Verwendung von IHttpActionResult als Rückgabetyp besteht darin, dass die ASP.NET-Web-API-Aktionsmethode der von MVC ähnelt. Sie können jedes Aktionsergebnis zurückgeben, ohne sich in Medienformatierern zu verfangen.

Wie Darrel bemerkt hat, können Sie natürlich die Aktionsergebnisse verketten und eine leistungsstarke Mikropipeline erstellen, die den Message-Handlern in der API-Pipeline selbst ähnelt. Dies ist abhängig von der Komplexität Ihrer Aktionsmethode.

Lange Rede kurzer Sinn - es ist nicht IHttpActionResult versus HttpResponseMessage. Im Grunde ist es, wie Sie die Antwort erstellen möchten. Mach es selbst oder durch eine Fabrik.

17
Badri

Die Web-API gibt grundsätzlich vier Objekttypen zurück: void, HttpResponseMessage, IHttpActionResult und andere starke Typen. Die erste Version der Web-API gibt HttpResponseMessage zurück, eine recht einfache HTTP-Antwortnachricht.

Das IHttpActionResult wurde von WebAPI 2 eingeführt, einer Art Wrap von HttpResponseMessage. Es enthält die Methode ExecuteAsync() zum Erstellen eines HttpResponseMessage. Dies vereinfacht das Testen von Steuergeräten.

Andere Rückgabetypen sind stark typisierte Klassen, die von der Web-API mithilfe eines Medienformatierers im Antworttext serialisiert werden. Der Nachteil war, dass Sie einen Fehlercode wie 404 nicht direkt zurückgeben können. Sie können lediglich einen HttpResponseException -Fehler auslösen.

5
Peter.Wang

Ich möchte lieber die TaskExecuteAsync-Schnittstellenfunktion für IHttpActionResult implementieren. So etwas wie:

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);

        switch ((Int32)_respContent.Code)
        { 
            case 1:
            case 6:
            case 7:
                response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);
                break;
            case 2:
            case 3:
            case 4:
                response = _request.CreateResponse(HttpStatusCode.BadRequest, _respContent);
                break;
        } 

        return Task.FromResult(response);
    }

, wobei _request die HttpRequest und _respContent die Payload ist.

3
appletwo

Die Verwendung von IHttpActionResult gegenüber HttpResponseMessage bietet folgende Vorteile:

  1. Mit dem IHttpActionResult konzentrieren wir uns nur auf die zu sendenden Daten, nicht auf den Statuscode. Hier wird der Code sauberer und sehr einfach zu pflegen sein.
  2. Unit-Tests der implementierten Controller-Methode werden einfacher.
  3. Verwendet standardmäßig async und await.
1
Debendra Dash