Olá, pessoal!
Hoje vou explicar validações que podem ser feitas com o uso de Data Annotations do Entityframework.
No meu último artigo, foi mostrado como criar uma Wep API com paginação, usando o MySQL e o EF, mas não me preocupei em fazer as validações, que são muito importantes em um ambiente real.
É a partir dessas validações que o cliente que está consumindo o serviço recebe as respostas corretas das requisições, sobre erros ou sobre alguma obrigatoriedade de dados que está sendo informada ou que precisa ser informada.
Vamos começar!
No primeiro artigo tínhamos uma classe/entidade Marca e as propriedades Id e DescricaoMarca. Como você pode ver na imagem abaixo, a classe não tinha nenhum tipo de validação, nem no nome da classe nem nas propriedades.
Utilizando o Data Annotations podemos melhorar essa classe, para que se algum dado vier incorreto ou mesmo não preenchido, retorne uma mensagem customizada para o cliente ou aplicação.
Podemos então adicionar as seguintes anotações:
[Required(ErrorMessage = "A descrição da marca é obrigatória.")] [MaxLength(100, ErrorMessage ="A descrição da marca só permite no máximo 100 caracteres.")]
A primeira anotação é a Required, que como a própria mensagem diz, é obrigatório o preenchimento desse campo; e a segunda é o MaxLength, que define o máximo de caracteres permitido naquele campo (no nosso caso ficou limitado a 100. Caso passe dessa quantidade, é retornada a mensagem de erro).
Como explicado no artigo anterior, o Id não necessita de nenhuma anotação, pois o EntityFramework já trata ele como chave primária, e sendo assim, ele já é Required e também Not Null.
Existem ainda muitas outras anotações para cada tipo de dado. Exemplos:
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")] – Formato de data. [Range(10, 25, ErrorMessage = "A Qtde deve está entre 5 e 10.")] - um range de valores, etc.
Porém, não basta fazer apenas as anotações para que a aplicação receba a resposta correta.
Se eu colocar as anotações e não testar no momento de um post, por exemplo, vai acontecer apenas um erro e não irá mostrar a resposta que foi personalizada nas anotações. Veja a imagem abaixo o erro que acontece se não fizermos uma verificação de validação antes:
Assim, podemos fazer uma validação antes de tentar adicionar um dado novo, usando o método ModelState. Será verificado se o que veio na requisição é válido. Caso a resposta seja falsa, entra no BadRequest retornando o status 400 e a mensagem que a gente definiu usando a Data Annotations:
Veja a resposta da requisição no PostMan:
No caso acima, não informei a descrição da marca para ocasionar o erro e obter o retorno.
Podemos ainda fazer algumas validações de forma diferente para os métodos GET, PUT, e DELETE para nossa API da seguinte forma:
No método PUT podemos fazer duas validação para ter certeza que a informação está correta, e caso não esteja, seja informada a mensagem que definimos.
Aqui verificamos se o id passado na url é o mesmo do corpo da requisição:
if (id != marca.Id) { return BadRequest("A URL contém um id diferente do id informado no corpo da requisição."); }
Nessa outra, verificamos se a marca existe no nosso banco de dados e, pra isso, fazemos uma consulta em todos as marcas passando o id. Caso não tenha, retorna NotFound (Não encontrado).
if (db.Marcas.Count(m => m.Id == id) == 0) { return NotFound(); }
Para o método Delete pode ser feito da seguinte forma:
Verificamos se o id é maior que zero, se não, retorna o BadRequest.
if (id <= 0) { return BadRequest("O id não pode ser zero."); }
Depois, fazemos uma busca no banco pelo Id, caso encontre o registro, será removido, se não encontrar, retorna um NotFound.
var marca = db.Marcas.Find(id); if (marca == null) { return NotFound(); }
E por fim, vamos fazer algumas validações no método GET, que retorna nossas marcas, onde ocorre a paginação da nossa API.
Primeiro verificamos se os parâmetros informados são menores que zero, depois verificamos se a quantidade de registro é maior que o limite permitido, e por último o total de páginas. Caso alguma das requisições seja verdadeira, retornamos um BadRequest com a mensagem personalizada para cada situação.
Pronto, pessoal! Fazendo as validações corretamente teremos uma API muito mais robusta e com respostas precisas nas requisições, evitando assim muita dor de cabeça tentando desvendar o motivo do erro.
Dediquem um tempo para estudar sobre Data Annotations. Com certeza vocês não vão se arrepender.
Vou ficando por aqui e até o próximo. Abraços!