type ihttpactionresult example error c# asp.net-web-api httpresponse

c# - example - ¿Por qué debo usar IHttpActionResult en lugar de HttpResponseMessage?



unauthorized ihttpactionresult (8)

He estado desarrollando con WebApi y pasé a WebApi2, donde Microsoft ha introducido una nueva Interfaz IHttpActionResult que parece ser recomendada para usar sobre la devolución de un HttpResponseMessage . Estoy confundido sobre las ventajas de esta nueva interfaz. Parece que, principalmente, solo proporciona una manera LIGERAMENTE más fácil de crear un HttpResponseMessage .

Yo diría que esto es "abstracción en aras de la abstracción". ¿Me estoy perdiendo de algo? ¿Cuáles son las ventajas del mundo real que obtengo al usar esta nueva Interfaz además de guardar una línea de código?

Camino antiguo (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(); } }


Aquí hay varios beneficios de IHttpActionResult over HttpResponseMessage mencionados en la documentación de Microsoft ASP.Net :

  • Simplifica la unidad de pruebas de sus controladores.
  • Mueve la lógica común para crear respuestas HTTP en clases separadas.
  • Aclara la intención de la acción del controlador al ocultar los detalles de bajo nivel de la construcción de la respuesta.

Pero aquí hay algunas otras ventajas de usar IHttpActionResult 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 involucra 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 Espera por defecto.
  • Fácil de crear su propio ActionResult simplemente implementando el método ExecuteAsync .
  • puede usar ResponseMessageResult ResponseMessage(HttpResponseMessage response) para convertir HttpResponseMessage en IHttpActionResult .

Esta es solo mi opinión personal y la gente del equipo de la API web probablemente pueda articularlo mejor, pero aquí está mi 2c.

En primer lugar, creo que no se trata de uno sobre el otro. Puede usarlos en función de lo que desee hacer en su método de acción, pero para comprender el poder real de IHttpActionResult , probablemente deba ApiController de los métodos de ayuda de ApiController como Ok , NotFound , etc.

Básicamente, creo que una clase que implementa IHttpActionResult como una fábrica de HttpResponseMessage . Con esa mentalidad, ahora se convierte en un objeto que debe devolverse y en una fábrica que lo produce. En el sentido general de la programación, puede crear el objeto usted mismo en ciertos casos y en ciertos casos, necesita una fábrica para hacerlo. Igual que aquí.

Si desea devolver una respuesta que deba construirse a través de una lógica compleja, digamos muchos encabezados de respuesta, etc., puede abstraer toda esa lógica en una clase de resultado de acción implementando IHttpActionResult y usarla en múltiples métodos de acción para devolver la respuesta.

Otra ventaja de usar IHttpActionResult como tipo de retorno es que hace que el método de acción de la API web de ASP.NET sea similar a MVC. Puedes devolver cualquier resultado de acción sin que te atrapen los formateadores de medios.

Por supuesto, como señala Darrel, puede encadenar resultados de acción y crear un micro-canalización potente similar a los controladores de mensajes en el canal de API. Esto necesitarás dependiendo de la complejidad de tu método de acción.

Larga historia corta: no es IHttpActionResult versus HttpResponseMessage . Básicamente, es cómo quieres crear la respuesta. Hazlo tú mismo oa través de una fábrica.


La API web básicamente devuelve 4 tipos de objeto: void , HttpResponseMessage , IHttpActionResult y otros tipos fuertes. La primera versión de la API web devuelve HttpResponseMessage que es un mensaje de respuesta HTTP bastante sencillo.

El IHttpActionResult fue introducido por WebAPI 2, que es un tipo de envoltura de HttpResponseMessage . Contiene el método ExecuteAsync() para crear un HttpResponseMessage . Simplifica las pruebas unitarias de su controlador.

Otros tipos de retorno son clases de tipo tipificado fuerte serializadas por la API web utilizando un formateador de medios en el cuerpo de la respuesta. El inconveniente fue que no puede devolver directamente un código de error como el 404. Todo lo que puede hacer es lanzar un error HttpResponseException .


Prefiero implementar la función de interfaz TaskExecuteAsync para IHttpActionResult. Algo como:

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); }

, donde _request es HttpRequest y _respContent es la carga útil.


Puede decidir no usar IHttpActionResult porque su código existente genera un HttpResponseMessage que no se ajusta a una de las respuestas enlatadas. Sin embargo, puede adaptar HttpResponseMessage a IHttpActionResult utilizando la respuesta enlatada de ResponseMessage . Me tomó un tiempo resolver 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 que ResponseMessage es un método de la clase base ApiController que su controlador debería heredar.


Tenemos los siguientes beneficios de usar IHttpActionResult over HttpResponseMessage :

  1. Al utilizar IHttpActionResult , solo nos concentramos en los datos que se enviarán, no en el código de estado. Así que aquí el código será más limpio y muy fácil de mantener.
  2. Las pruebas unitarias del método del controlador implementado serán más fáciles.
  3. Utiliza async y await por defecto.

Todavía puede utilizar HttpResponseMessage . Esa capacidad no desaparecerá. Sentí lo mismo que tú y discutí ampliamente con el equipo que no había necesidad de una abstracción adicional. Hubo algunos argumentos para intentar justificar su existencia, pero nada me convenció de que valía la pena.

Es decir, hasta que vi this muestra de Brad Wilson . Si construye IHttpActionResult clases IHttpActionResult de una manera que se puede encadenar, obtiene la capacidad de crear una línea de respuesta de "nivel de acción" para generar el HttpResponseMessage . Bajo las carátulas, así es como se implementan los ActionFilters , sin embargo, el orden de esos ActionFilters no es obvio cuando se lee el método de acción, que es una de las razones por las que no soy fanático de los filtros de acción.

Sin embargo, al crear un IHttpActionResult que puede ser encadenado explícitamente en su método de acción, puede componer todo tipo de comportamiento diferente para generar su respuesta.


// this will return HttpResponseMessage as IHttpActionResult return ResponseMessage(httpResponseMessage);