Skip to content

Instantly share code, notes, and snippets.

@Whistler092
Last active May 9, 2021 05:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Whistler092/1faca5a555bff47ccb42195344120589 to your computer and use it in GitHub Desktop.
Save Whistler092/1faca5a555bff47ccb42195344120589 to your computer and use it in GitHub Desktop.
Filter with BadRequest

La finalidad de realizar este filtro es para organizar un poco la respuesta de un Action cuando un modelo no es valido.

En el controlador, solamente se requiere tener el decorador de [ApiController] y : ControllerBase. La accion podria ser algo como la siguiente


[HttpPost]
public async Task<ActionResult> Post([FromBody] Genero genero)
{
    context.Add(genero);
    await context.SaveChangesAsync();
    return NoContent();
}

El API Controller valida el modelo y si el modelo no es valido, de inmediato retorna un badrequest.

Sin el filtro, el objeto que se retorna seria el siguiente


{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-90c775c93bbecc4fb029a8d031227d1f-2376cbde7016724b-00",
    "errors": {
        "Nombre": [
            "The field Nombre must be a string with a maximum length of 50.",
            "La primera letra debe ser mayúscula"
        ]
    }
}

Con el filtro seria así

[
    "Nombre: The field Nombre must be a string with a maximum length of 50.",
    "Nombre: La primera letra debe ser mayúscula"
]

Mas facil de manipular en el frontend.

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace API.ApiBehavior
{
public static class BehaviorBadRequests
{
public static void Parsear(ApiBehaviorOptions options)
{
options.InvalidModelStateResponseFactory = actionContext =>
{
var respuesta = new List<string>();
foreach (var llave in actionContext.ModelState.Keys)
{
foreach (var error in actionContext.ModelState[llave].Errors)
{
respuesta.Add($"{llave}: {error.ErrorMessage}");
}
}
return new BadRequestObjectResult(respuesta);
};
}
}
}
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
namespace API.Filtros
{
public class ParsearBadRequest : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
var cast = context.Result as IStatusCodeActionResult;
if (cast == null)
return;
if (cast.StatusCode == 400)
{
var respuesta = new List<string>();
var resultadoActual = context.Result as BadRequestObjectResult;
if (resultadoActual.Value is string)
{
respuesta.Add(resultadoActual.Value.ToString());
}
else
{
foreach (var llave in context.ModelState.Keys)
{
foreach (var error in context.ModelState[llave].Errors)
{
respuesta.Add($"{llave}: {error.ErrorMessage}");
}
}
}
}
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}
}
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.Filters.Add(typeof(ParsearBadRequest));
}).ConfigureApiBehaviorOptions(BehaviorBadRequests.Parsear);
//...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment