Creación de nuevos métodos de resultado de acción IHttpActionResult


¿Hay alguna forma de usar la nueva interfaz IHttpActionResult para devolver un mensaje de respuesta HttpStatusCode.NoContent?

Actualmente estoy usando return new HttpResponseMessage( HttpStatusCode.NoContent ); y quisiera convertir esto en return NoContent();.

IHttpActionResult ya tiene Ok(), Conflict() y NotFound(), pero no puedo encontrar ninguna para Forbidden() y NoContent() que debo utilizar en mi proyecto.

¿Qué tan fácil es agregar otros tipos de resultados?

Author: Liam, 2015-02-05

4 answers

No hay un método de conveniencia para el resultado no-content porque, por defecto, cuando una acción devuelve void, la respuesta tendrá el estado HTTP 204.

Si desea indicar explícitamente que en la acción, también podría devolver un StatusCode(HttpStatusCode.NoContent) de su acción o un

ResponseMessage(new HttpResponseMessage(HttpStatusCode.NoContent)).

El método de conveniencia Unauthorized() le da un estado 401 por lo que, para Forbidden (403), también tendría que usar StatusCode(HttpStatusCode.Forbidden) o

ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden))
 40
Author: Rafael Companhoni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-15 23:31:20

Encontré este sitio de ejemplo que muestra cómo agregar un método personalizado IHttpActionResult y lo he utilizado para crear los métodos Forbidden() y NoContent() con gran éxito.

public abstract class CommonApiController : ApiController
{
    public class ForbiddenResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly string _reason;

        public ForbiddenResult(HttpRequestMessage request,string reason)
        {
            _request = request;
            _reason = reason;
        }

        public ForbiddenResult(HttpRequestMessage request)
        {
            _request = request;
            _reason = "Forbidden";
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = _request.CreateResponse(HttpStatusCode.Forbidden,_reason);
            return Task.FromResult(response);
        }
    }

    public class NoContentResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly string _reason;

        public NoContentResult(HttpRequestMessage request,string reason)
        {
            _request = request;
            _reason = reason;
        }

        public NoContentResult(HttpRequestMessage request)
        {
            _request = request;
            _reason = "No Content";
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = _request.CreateResponse(HttpStatusCode.NoContent,_reason);
            return Task.FromResult(response);
        }
    }
}

Y luego puedo usarlo así:

public class InvoiceController : CommonApiController
{
    public async Task<IHttpActionResult> Post([FromBody]Invoice invoice)
    {
        if(User.IsInRole("Readonly"))
        {
            return Forbidden();
        }

        // Rest of code

    }
}
 23
Author: Intrepid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-06 08:20:35

Probé la implementación @Intrepid y me encontré con algunos problemas. Veo dos soluciones aquí:

Solución 1: La parte: return Forbidden(); no debería funcionar.

El compilador no reconocería esto.

En cambio debería ser: return new ForbiddenResult(Request, "my reason");

ACTUALIZACIÓN 1

Solución 2:

Creo que esto es lo que @Interpid pretendía en su implementación, pero le faltaban algunas cosas.

Para utilizar return Forbidden(); el CommonApiController debe actualizarse con las funciones que devuelven el personalizado IHttpActionResult para Forbidden y NoContent

La clase debería tener este aspecto:

public abstract class CommonApiController: ApiController {

    protected ForbiddenResult Forbidden() {
     return new ForbiddenResult(this.Request);
    }

    protected ForbiddenResult Forbidden(string reason) {
     return new ForbiddenResult(this.Request, reason);
    }

    protected NoContentResult NoContent() {
     return new NoContentResult(this.Request);
    }

    protected NoContentResult NoContent(string reason) {
     return new NoContentResult(this.Request, reason);
    }

    public class ForbiddenResult: IHttpActionResult {
     private readonly HttpRequestMessage _request;
     private readonly string _reason;

     public ForbiddenResult(HttpRequestMessage request, string reason) {
      _request = request;
      _reason = reason;
     }

     public ForbiddenResult(HttpRequestMessage request) {
      _request = request;
      _reason = "Forbidden";
     }

     public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken) {
      var response = _request.CreateResponse(HttpStatusCode.Forbidden, _reason);
      return Task.FromResult(response);
     }
    }

    public class NoContentResult: IHttpActionResult {
     private readonly HttpRequestMessage _request;
     private readonly string _reason;

     public NoContentResult(HttpRequestMessage request, string reason) {
      _request = request;
      _reason = reason;
     }

     public NoContentResult(HttpRequestMessage request) {
      _request = request;
      _reason = "No Content";
     }

     public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken) {
      var response = _request.CreateResponse(HttpStatusCode.NoContent, _reason);
      return Task.FromResult(response);
     }
    }
   }

De todos modos, si me equivoco y la respuesta de @Interpid es correcta. ¿Qué me estoy perdiendo aquí para hacer que su implementación funcione?

 7
Author: Asaf Epelbaum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-10 09:13:13

Si quieres incluir una frase reason con tu respuesta sin añadir una subclase a ApiController, construye un objeto ResponseMessage y devuélvelo desde la acción del método ResponseMessage (). Prueba esto:

public class InvoiceController : ApiController
{
    public async Task<IHttpActionResult> Post([FromBody]Invoice invoice)
    {
        if(User.IsInRole("Readonly"))
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);

            response.ReasonPhrase = "User has the Readonly role";
            return ResponseMessage(response);
        }

        // Rest of code

    }
}
 3
Author: kmac.mcfarlane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-23 15:51:26