Validaciones estándar y personalizadas en un API con .NET
Validar en un API no es una opción, sino una obligación. Aprende a hacerlo de la mejor forma aquí 🐿️🙌

Las validaciones son algo obligatorio hoy en día cuando desarrollamos un API, independientemente de la tecnología que usemos, hoy veremos los tipos de validaciones que existen.

En este artículo te mostraré los 3 tipos de validaciones que existen en un API hecho con .NET. Comencemos! 🐿️✌️

Por Validaciones Estándar

Este tipo de validaciones son por atributo y que .NET pone a disposición como un mecanismo que permite validar automáticamente los datos de entrada basados en los atributos aplicados a las propiedades de un modelo o entidad.

Tenemos varias validaciones por atributos existentes en .NET para que las utilices directamente como:

  • Required
  • StringLength
  • RegularExpression
  • Range
  • EmailAddress
  • Compare

La forma de aplicarla es directamente al modelo o entidad así:

public class Libro
{ 
    public int Id {get; set;} 
    [Required]
    [StringLength(50)] 
    public string BookName {get; set;} 
}

Por Atributos personalizados

Son similares a las estándar ya que son por atributo, sin embargo tú las crear según necesites.

Si quieres crear tu propia validación puedes hacerlo así:

Crea la siguiente clase en una carpeta que puedes llamar por ejemplo: Validaciones

	public class PrimeraLetraMayusculaAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null || string.IsNullOrEmpty(value.ToString()))
                return ValidationResult.Success; //Retorno success porque Required es la que se encargaría de validar esto y no debes hacer doble validacion o redundar. (Single responsibility)
            
            var primeraLetra = value.ToString()[0].ToString();

            if (primeraLetra != primeraLetra.ToUpper())
                return new ValidationResult("La primera letra debe ser mayúscula.");
            
            return ValidationResult.Success;
        }
    }

Esta es una validación personalizada que se asegura que el valor de una propiedad comience con una letra mayúscula. La aplicarías así a una entidad:

public class Libro
{
    public int Id {get; set;}
    [PrimeraLetraMayusculaAttribute]
    public string BookName {get; set;}
}

Por modelo

Este tipo de validación se hace a nivel de la entidad o modelo, es decir de una clase.

La forma de aplicarla es la siguiente:

    public class Numeros: IValidatableObject
    {        
        public int Menor { get; set; }
        public int Mayor { get; set; }
        
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (Menor > Mayor)
			    yield return new ValidationResult("El campo menor debe ser menor o igual al campo mayor.", new string[] { nameof(Menor) });
        }
    }

Allí hemos validado que una propiedad sea mayor que otra en una entidad llamada Numeros.

Por lógica de negocio

Son aquellas validaciones propias del negocio que normalmente van en la capa de Servicios (es lo recomendado ya que esta capa es la encargada de manejar la lógica de negocios), o en el controlador.

Veamos este ejemplo que por didáctica he añadido la lógica de negocio en el controlador, aunque como he mencionado esto debería estar en otra capa, no directamente en el API.

		[HttpPost]
        public async Task<ActionResult> Post([FromBody]Libro libro)
        {
            var existeAutor = await context.Autores.AnyAsync(x => x.Id == libro.AutorId);
            if (!existeAutor)
                return NotFound($"no existe el autor con id {libro.AutorId}");

            var existeAutorMismoNombre = await context.Libros.AnyAsync(x => x.Titulo == libro.Titulo);
            if (existeAutorMismoNombre)
                return BadRequest("Ya existe un libro con el mismo título");

            await context.Libros.AddAsync(libro);
            await context.SaveChangesAsync();
            return Ok();
        }

Aquí estoy validando cosas comunes al negocio, por ejemplo valido que un autor exista antes de insertar un libro, y valido también que no se guarden dos libros con el mismo nombre.

Jerarquía

Existe una jerarquía cuando se aplican estas validaciones, es decir existe un orden que se sigue cuando se aplican estas validaciones y es el siguiente:

[1] Validaciones Estándar > [2] Atributos personalizados > [3] Por modelo > [4] Por lógica de negocio

Si esta entrada te ha gustado, entonces compártela genio!

Créditos de foto de portada: Foto de Magnet.me en Unsplash

Deja una respuesta

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