Saltar al contenido

¿Cómo realizar la validación del modelo en cada método en ASP.NET Core Web API?

Solución:

¿Cómo comprobar el estado del modelo?

Compruebe el controlador ModelState en la acción para obtener el estado del modelo.

obtener una cadena legible de todos los errores y devolver una BadRequest con este error?

Usar BadRequest(ModelState) para devolver una respuesta de solicitud incorrecta HTTP que inspeccionará el estado del modelo y construirá el mensaje utilizando errores.

Código completo

/// <summary>
/// API endpoint to login a user
/// </summary>
/// <param name="data">The login data</param>
/// <returns>Unauthorizied if the login fails, The jwt token as string if the login succeded</returns>
[AllowAnonymous]
[Route("login")]
[HttpPost]
public IActionResult Login([FromBody]LoginData data) {
    if(ModelState.IsValid) {
        var token = _manager.ValidateCredentialsAndGenerateToken(data);
        if (token == null) {
            return Unauthorized();
        } else {
            return Ok(token);
        }
    }
    return BadRequest(ModelState);
}

Por supuesto, podría escribirlo todo yo mismo en un método auxiliar … ¿Pero pensé en un filtro, tal vez?

Para evitar lo repetido ModelState.IsValid código en cada acción donde se requiere la validación del modelo, puede crear un filtro para verificar el estado del modelo y cortocircuitar la solicitud.

Por ejemplo

public class ValidateModelAttribute : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext context) {
        if (!context.ModelState.IsValid) {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }
}

Se puede aplicar a la acción directamente.

[ValidateModel] //<-- validation
[AllowAnonymous]
[Route("login")]
[HttpPost]
public IActionResult Login([FromBody]LoginData data) {
    var token = _manager.ValidateCredentialsAndGenerateToken(data);
    if (token == null) {
        return Unauthorized();
    } else {
        return Ok(token);
    }    
}

o agregado globalmente para ser aplicado a todas las solicitudes donde se debe verificar el estado del modelo.

Validación del modelo de referencia en ASP.NET Core MVC

Recomiendo encarecidamente usar [ApiController] y otros atributos que ayudan a facilitar la validación en proyectos basados ​​en API web.

[ApiController] este atributo realiza toda la validación básica en el modal antes de ingresar al método. Por lo tanto, solo tiene que inspeccionar el modal si desea realizar algún tipo de validación personalizada.

Para verificar si el estado del modelo es válido, use la propiedad ModelState (expuesta por la clase ControllerBase de la que hereda la clase Controller)

ModelState.IsValid

Para obtener los errores del ModelState, puede filtrar los errores del diccionario y devolverlos como una lista

var errors = ModelState
    .Where(a => a.Value.Errors.Count > 0)
    .SelectMany(x => x.Value.Errors)
    .ToList();

Una opción es validar el estado en cada método / controlador, pero le recomiendo implementar la validación en una clase base que valida el modelo en el
OnActionExecuting método como este

public class ApiController : Controller
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!ModelState.IsValid)
        {
            var errors = ModelState
                .Where(a => a.Value.Errors.Count > 0)
                .SelectMany(x => x.Value.Errors)
                .ToList();
            context.Result = new BadRequestObjectResult(errors);
        }
        base.OnActionExecuting(context);
    }
}

Entonces, cada controlador que debería tener una validación automática del estado del modelo simplemente hereda de la clase base

public class TokenController : ApiController
{
    /// <summary>
    /// API endpoint to login a user
    /// </summary>
    /// <param name="data">The login data</param>
    /// <returns>Unauthorizied if the login fails, The jwt token as string if the login succeded</returns>
    [AllowAnonymous]
    [Route("login")]
    [HttpPost]
    public IActionResult Login([FromBody]LoginData data)
    {
        var token = _manager.ValidateCredentialsAndGenerateToken(data);
        if (token == null)
        {
            return Unauthorized();
        }
        else
        {
            return Ok(token);
        }
    }
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *