¿Por qué debería utilizar IHttpActionResult en lugar de HttpResponseMessage?
He estado desarrollando con WebApi y pasé a WebApi2, donde Microsoft introdujo una nueva IHttpActionResult
interfaz que parece recomendar su uso en lugar de devolver un archivo HttpResponseMessage
. Estoy confundido acerca de las ventajas de esta nueva interfaz. Parece principalmente proporcionar una forma LIGERAMENTE más fácil de crear un archivo HttpResponseMessage
.
Yo diría que esto es "abstracción por el simple hecho de abstraerse". ¿Me estoy perdiendo de algo? ¿Cuáles son las ventajas del mundo real que obtengo al usar esta nueva interfaz además de quizás guardar una línea de código?
Manera antigua (WebApi):
public HttpResponseMessage Delete(int id)
{
var status = _Repository.DeleteCustomer(id);
if (status)
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
Nueva forma (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();
}
}
Es posible que decida no utilizarlo IHttpActionResult
porque su código existente genera un mensaje HttpResponseMessage
que no se ajusta a una de las respuestas predeterminadas. Sin embargo, puedes adaptarte HttpResponseMessage
al IHttpActionResult
uso de la respuesta predeterminada de ResponseMessage
. Me tomó un tiempo darme cuenta de esto, así que quería publicarlo mostrando que no necesariamente tienes que elegir uno u otro:
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;
}
Tenga en cuenta ResponseMessage
que es un método de la clase base ApiController
del que su controlador debería heredar.
Todavía puedes usar HttpResponseMessage
. Esa capacidad no desaparecerá. Sentí lo mismo que usted y discutí extensamente con el equipo que no había necesidad de una abstracción adicional. Se lanzaron algunos argumentos para intentar justificar su existencia, pero nada que me convenciera de que valiera la pena.
Es decir, hasta que vi esta muestra de Brad Wilson . Si construye IHttpActionResult
clases de una manera que pueda encadenarse, obtendrá la capacidad de crear un canal de respuesta de "nivel de acción" para generar el archivo HttpResponseMessage
. Debajo de las sábanas, así es como ActionFilters
se implementan; sin embargo, el orden de ellos ActionFilters
no es obvio al leer el método de acción, lo cual es una de las razones por las que no soy fanático de los filtros de acción.
Sin embargo, al crear un método IHttpActionResult
que se puede encadenar explícitamente en su método de acción, puede componer todo tipo de comportamientos diferentes para generar su respuesta.
Aquí hay varios beneficios de lo mencionado IHttpActionResult
anteriormente HttpResponseMessage
en la documentación de Microsoft ASP.Net :
- Simplifica la prueba unitaria de sus controladores.
- Mueve la lógica común para crear respuestas HTTP a clases separadas.
- Hace que la intención de la acción del controlador sea más clara al ocultar los detalles de bajo nivel de la construcción de la respuesta.
Pero aquí hay algunas otras ventajas de su uso IHttpActionResult
que vale la pena mencionar:
- Respetar el principio de responsabilidad única : hacer que los métodos de acción tengan la responsabilidad de atender las solicitudes HTTP y no los involucre en la creación de los mensajes de respuesta HTTP.
- Implementaciones útiles ya definidas en System.Web.Http.Results, a saber:
Ok
NotFound
Exception
Unauthorized
BadRequest
Conflict
Redirect
InvalidModelState
( enlace a la lista completa ) - Utiliza Async y Await de forma predeterminada.
- Fácil de crear su propio ActionResult simplemente implementando
ExecuteAsync
el método. - puede utilizar
ResponseMessageResult ResponseMessage(HttpResponseMessage response)
para convertir HttpResponseMessage a IHttpActionResult .