Tengo un DTO que es un parámetro de entrada para el punto final POST de la API.
El DTO tiene anotaciones de datos y la validación se realiza automáticamente. El siguiente es un ejemplo:
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-f14406a8950b1005234cc79298a79586-77222ebbed97e453-00", "errors": { "Email": [ "The Email field is not a valid e-mail address." ] } }Sin embargo, cuando quiero generar una respuesta 400 desde el controlador, uso cualquiera de los siguientes:
return BadRequest("some message") Esto devuelve some message
Donde así: return BadRequest(new { message = "some message"}); devoluciones:
{ "message": "some message" }¿Cómo garantizar que se utilice el mismo formato en todo el proceso? ¿Hay alguna forma incorporada de estandarizar?
Según la documentación: https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-6.0#default-badrequest-response
El tipo ValidationProblemDetails:
Para que las respuestas automáticas y personalizadas sean coherentes, llame al método ValidationProblem en lugar de BadRequest .
ValidationProblem devuelve un objeto ValidationProblemDetails, así como la respuesta automática.
Ejemplo:
ModelState.AddModelError("Name", "Invalid name"); return ValidationProblem(ModelState); Puede usar este concepto en todos los códigos de respuesta, por ejemplo, en lugar de 400 (predeterminado para ValidationProblem ), puede devolver 401 con el código anterior reemplazando la última línea con lo siguiente:
return ValidationProblem(modelStateDictionary:ModelState, statusCode:401)Sin embargo, si no desea utilizar este formato de respuesta y desea tener uno propio, debe deshabilitar el middleware responsable de la validación automática del modelo y la respuesta 400 :
En program.cs :
builder.Services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.SuppressModelStateInvalidFilter=true; }); Ahora en el controlador tendrá que hacer las validaciones usted mismo (ejemplo: verificar si hay nulos) y return BadRequest(new {error = "type something here"};
Cree un controlador api base de la siguiente manera:
[ApiController] public abstract class ApiControllerBase : ControllerBase { protected virtual IActionResult InvalidModelState() { return HttpContext.RequestServices.GetService<IOptions<ApiBehaviorOptions>>() .Value.InvalidModelStateResponseFactory(ControllerContext); } } Y derive sus controladores api de ApiControllerBase . Siempre que desee agregar errores y usar el mismo formato de errores de validación, simplemente agregue un ModelState.AddModelError("", "Your error message") y luego return InvalidModelState(); .