0

👨‍💻️ Validando dados com Fluent Validation em uma aplicação MVC e WebAPI

Pablo Nazareth
Pablo Nazareth

Introdução


O Fluent Validation é uma biblioteca disponível para o .NET/.NET Core (incluindo também as versões mais recentes), para realizar validação de classes usadas como View Models, Commands (conceito de CQRS), DTOs (objetos de transferência de dados), ou entidades de domínio.


O seu objetivo é de realizar a implementação de regras de validação de forma simples e rápida, baseando-se em métodos encadeados e expressões lambdas.

Nesse artigo iremos implementar regras de validações disponíveis nessa biblioteca, criar as nossas próprias regras e também aprender a como utilizar em projetos MVC e WebAPI.


Instalação



  1. Crie um projeto de acordo com o tipo desejado (exemplo ASP.NET Web MVC ou ASP.NET Web API). Iremos demonstrar a utilização tanto em uma aplicação MVC quanto WebAPI.
  2. Instale o Fluent Validation através do ‘.NET CLI’ ou ‘Package Manager’


.NET CLI:

dotnet add package FluentValidation

dotnet add package FluentValidation.AspNetCore


Package Manager:

Install-Package FluentValidation

Install-Package FluentValidation.AspNetCore

Observação: caso queira baixar uma versão específica do FluentValidation, verifique as versões disponíveis clicando aqui e aqui


Configuração

Depois de instalado, precisamos configurar o FluentValidation na classe ‘Startup.cs’ da aplicação. Adicione a utilização das bibiliotecas abaixo:

using FluentValidation.AspNetCore;
using System.Reflection;


Observação: A biblioteca ‘System.Reflection’, será necessária para a implementação do que iremos ver a seguir.

No método de extensão dentro do ‘ConfigureServices’, deverá realizar o método de chamada do FluentValidation, logo após o código de adicionar o MVC:


services.AddMvc(setup => {
      // Implementação de código MVC...
    }).AddFluentValidation(fv => fv.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly()));
}


No exemplo anterior, incluímos o código ‘RegisterValidatorsFromAssembly’, para que seja possível a descoberta e registro automático de todas as nossas classes de validação do nosso Assembly.

Como alternativa a essa solução, você pode também utilizar o método ‘RegisterValidatorsFromAssemblyContaining<Objeto>()’, onde ‘objeto’ será qual a classe ou interface das classes de validação.


Implementando regras de validação

Com o nosso ambiente criado e configurado, iremos agora implementar as nossas regras de validação. Vamos lá? 👨‍💻️



Iremos primeiro criar a nossa classe ‘Cliente’ como exemplo:

public class Cliente
{
  public string Nome { get; set; }
  public string Email { get; set; }
  public DateTime DataNascimento { get; set; }
  public string Telefone { get; set; }
}


Em seguida, será criado a classe de validação de cliente, a qual deverá implementar a classe abstrata ‘AbstractValidator’ do Fluent Validation.

Podemos criar uma classe separada com o nome de ‘ClienteValidation.cs’ ou usar o conceito de ‘classe aninhada’, a qual iremos incluir logo abaixo dessa classe cliente:


using FluentValidation; // Adicionar no topo da classe
public class ClienteValidation : AbstractValidator<Cliente>
{
   public ClienteValidation()
   {
      // Aqui será implementado as nossas regras
   }
}


No site oficial do FluentValidation, há uma lista completa de todas as regras de validações existentes. Abaixo exemplo de utilização de algumas regras:

RuleFor(x => x.Nome)
 .NotEmpty().WithMessage("Informe o nome do cliente")
 .Length(3,50).WithMessage("O nome deverá ter entre 3 a 50 caracteres");

RuleFor(x => x.Email)
  .NotEmpty().WithMessage("Informe o e-mail do cliente")
  .EmailAddress().WithMessage("E-mail inválido");

RuleFor(x => x.DataNascimento)
  .NotEmpty().WithMessage("Informe a data de nascimento do cliente");


Criando Regras de Validação

Em alguns cenários poderá ocorrer de precisarmos de uma validação a qual a biblioteca do FluentValidation ainda não possui. Há duas formas de ser feita, podemos utilizar o método ‘Must’, ou criar um método de extensão do FluentValidation.


  1. Utilizando o ‘Must’

No exemplo abaixo, adicionamos uma regra para o campo ‘Data Nascimento’, em que o usuário deverá ter 18 anos ou mais:

RuleFor(x => x.DataNascimento)
  .NotEmpty().WithMessage("Informe a data de nascimento do cliente");
  .Must(ClienteMaiorDeIdade).WithMessage("O cliente deverá ter no mínimo 18 anos");

private static bool ClienteMaiorDeIdade(DateTime dataNascimento) =>
  dataNascimento <= DateTime.Now.AddYears(-18);

  1. Criando método de extensão

Iremos criar uma regra de validação para o nosso campo ‘Telefone’, para que seja possível apenas valores numéricos.

No exemplo abaixo, criamos dentro de uma classe o nosso método de extensão para validação dessa regra:

using System.Text.RegularExpressions;
using FluentValidation;
namespace medium_dio_artigo_fluentvalidation.Extensions
{
  public static class FluentExtensions
  {
    public static IRuleBuilderOptions<T, TElement> Phone<T,  TElement>(this IRuleBuilder<T, TElement> ruleBuilder) =>   ruleBuilder.Must((_, value, _) => value?.ToString().Length == 12 && Regex.IsMatch(value.ToString(), "^[0-9]*$"));
  }
}


A utilização da regra é simples, basta apenas realizar a chamada do método:

RuleFor(x => x.Telefone)
  .Phone().WithMessage("Informe um número de telefone válido.");


Viu como é fácil implementar? agora você poderá criar qualquer tipo de regra de validação para a sua aplicação 😀️



Aplicação MVC

Na aplicação MVC, realizamos na View a identificação de cada campo. Exemplo do campo Nome:

<div class="form-group">
  <label asp-for="Nome" class="col-md-2 control-label"></label>
  <div class="col-md-10">
    <input asp-for="Nome" class="form-control" />
    <span asp-validation-for="Nome" class="text-danger"></span>
  </div>
</div>


No nosso Controller, podemos utilizar o ‘ModelState.IsValid’ para saber se a nossa model possui ou não algum erro de validação:

public IActionResult Create(Cliente model)
{
   if (ModelState.IsValid) return RedirectToAction("Index", "Home");
   return View(model);
}


Veja como será o resultado, caso algum campo estiver inválido:


Aplicação WebAPI

Iremos implementar uma API a qual irá receber como payload os dados do Cliente. O FluentValidation será responsável por realizar a validação do nosso payload, no momento em que for acionado a nossa rota. Caso existir algum dado incorreto, será retornado automaticamente a informação.

[ApiController]
[Route("[controller]")]
public class ClienteController : ControllerBase
{
  [HttpPost]
  public IActionResult Post([FromBody] Cliente _) => Ok();
}


Caso algum campo estiver inválido, será retornado um status code 400 (Bad Request), contendo no campo “errors” um array contendo os erros de validação de cada propriedade.


Conclusão

Espero que com esse artigo você consiga aprender sobre o Fluent Validation e a sua aplicação. É uma biblioteca extremamente flexível e poderosa, que irá lhe ajudar bastante no dia-a-dia.


Código fonte do projeto utilizado:

GitHub da aplicação MVC: mvc

GitHub da aplicação WebAPI: webapi


Gostou do artigo? deixe a sua opinião com sugestões/críticas para que eu possa trazer mais conteúdo e ajudar a todos. Lembre-se de me seguir para acompanhar todos os meu próximos artigos, e até breve! 😉️


GitHub: pablochristian

LinkedIn: @pablo-christian



0
0

Comentários (1)

0
Marlon Menezes

Marlon Menezes

10/04/2021 11:25

Parabéns Pablo.

Como sempre trazendo conteúdo de qualidade.

Arquiteto de Software | Engenheiro de Software | Desenvolvedor FullStack | .NET Core | C# | Javascript | Angular |MCP

Brasil