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!