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();
}
}
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.
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.
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:
Ok
NotFound
Exception
Unauthorized
BadRequest
Conflict
Redirect
InvalidModelState
( Link zur vollständigen Liste )ExecuteAsync
.ResponseMessageResult ResponseMessage(HttpResponseMessage response)
verwenden, um HttpResponseMessage in IHttpActionResult zu konvertieren.// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage);
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.
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.
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.
Die Verwendung von IHttpActionResult
gegenüber HttpResponseMessage
bietet folgende Vorteile:
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.async
und await
.