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