ASP.NET
Core
Web API - Tratamento de erros - I
![]() |
Neste artigo vamos apresentar uma abordagem de tratamento de erros que pode ser usada em aplicações ASP .NET Core Web API. |
No .NET Core as aplicações MVC e WEB API agora possuem os mesmos controladores para as Actions; no entanto, apesar da semelhança, o tratamento de erros é feito de forma distinta nas respectivas aplicações.
![]() |
Como as Actions das aplicações MVC são executadas como resultado de uma ação do usuário no navegador, retornar uma página de erro ao navegador é uma abordagem correta. Nas aplicações Web API a abordagem já diferente.
Como as chamadas de uma API são em geral feitas pelo código do backend ou javascript e, o procedimento padrão é verificar o código de status e analizar a resposta para determinar se a ação foi executada com sucesso exibindo dados ao usuário se necessário. Gerar uma página de erro HTML é inútil nessas situações pois o retorno esperado é em geral JSON ou XML.
Apesar desse comportamento diferente, o fluxo do tratamento de erro usado , é praticamente o mesmo nas aplicações MVC e Web API.
Vejamos algumas abordagens usadas para o tratamento de erros em uma Web API.
Nos exemplos do artigo estou usando o Visual Studio 2019 Community e a ASP .NET Core 2.2.
Usando a abordagem padrão
Em uma aplicação WEB API, quando ocorre uma requisição inválida, o retorno de um response body vazio, embora não seja o ideal pode ser suficiente para indicar o cliente do processamento inválido.
Retornar um código de status 404 (sem corpo de resposta) para uma rota inexistente na API já pode ser suficiente para informar o cliente que corrija a sua requisição.
Essa geralmente é a abordagem padrão com configuração zero, e é o que o framework ASP.NET Core nos fornece.
Agora, quando um cliente passa dados inválidos, retornar um código de status 400, por exemplo, pode não ser suficiente para o cliente idenficar o problema. O correto é informar quais campos estão incorretos e retornar uma mensagem específica para cada campo inválido.
Isso é muito simples de fazer na ASP .NET Core usando os atributos de validação internos pré-existentes e disponíveis no namespace System.ComponentModel.DataAnnotations sendo muito usados para aplicações ASP .NET Core MVC.
Para aplicações WEB API podemos usar a abordagem usar o método Validate() da interface IValidatableObject retornando a informação de validação para o cliente no formato JSON.
Nota: Outra abordagem é criar uma classe que herda de ValidationAttribute e sobrescrever o método IsValid(). Para detalhes veja este artigo.
Como exemplo para um modelo de domínio Produto :
using System.Collections.Generic; using System.ComponentModel.DataAnnotations;
namespace ProdutosApi.Model
public IEnumerable<ValidationResult>
Validate(ValidationContext validationContext)
} |
Implementamos a interface IValidatableObject e o método Validate() definindo regras de validação para nome.
Usando o seguinte método Action HttpPost no Controlador:
[HttpPost]
public async Task<ActionResult<Produto>> PostProduto(Produto item)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_ctx.Produtos.Add(item);
await _ctx.SaveChangesAsync();
return CreatedAtAction(nameof(GetProduto), new { id = item.ProdutoId }, item);
}
|
Nota: O código destacado em azul na versão 2.2 da ASP .NET Core é chamado implicitamente, não sendo necessário ser escrito. Veja detalhes aqui.
Fazendo uma requisição POST usando o Postman, para criar um novo produto com dados do nome do produto inválido (usamos apenas 3 caracteres), temos o resultado abaixo:
Vemos o
retorno no formato JSON indicando claramente o problema de campo inválido
relativo ao nome.
Retornando informação adicional para erros específicos
Geralmente podemos retornar o código de status para um erro ocorrido em um request, mas existem casos que isso não é suficiente para identificar a falha.
Veja por
exemplo o código de status 404 que pode ter os
seguintes significados:
- O domínio está correto, mas a URL não corresponde a uma
rota existente;
- A URL é mapeada corretamente para uma rota, mas o recurso não existe;
- O request esta sendo feito para um endereço incorreto;
Se pudéssemos fornecer informações para distinguir entre esses casos, isso
poderia ser muito útil para um cliente.
Vejamos o caso do recurso não encontrado que pode acontecer quando informamos um id inexistente para localizar um produto:
O código abaixo mostra uma forma de resolver esse problema:
[HttpGet("{id}")]
public async Task<ActionResult<Produto>> GetProduto(int id)
{
var produto = await _ctx.Produtos.FindAsync(id);
if (produto == null)
{
return NotFound($"Produto não encontrado com o id ={id} informado");
}
return produto;
}
|
Veja no Postman o resultado de um request para um id inexistente:
Agora estamos retornando uma mensagem mais clara, o problema é que ela esta no formato texto sem formatação e não no formato JSON o que pode levar a inconsistências no tratamento da resposta.
Para resolver esse problema podemos usar o código a seguir no lugar do anterior:
[HttpGet("{id}")]
public async Task<ActionResult<Produto>> GetProduto(int id)
{
var produto = await _ctx.Produtos.FindAsync(id);
if (produto == null)
{
return NotFound(new { message = $"Produto de id={id} não encontrado" });
}
return produto;
}
|
Testando novamente no Postman para um id inexistente teremos agora o resultado abaixo:
Observe que agora a resposta esta no formato JSON.
Na próxima parte do artigo veremos como customizar o tratamento da resposta de forma mais estruturada.
"Disse-lhes, pois, Jesus: Quando levantardes o Filho do homem, então conhecereis
que EU SOU, e que nada faço por mim mesmo; mas isto falo como meu Pai me
ensinou."
João 8:28
Veja os
Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique
e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
ASP .NET Core 2 - MiniCurso Básico - Macoratti
ASP .NET Core - Macoratti
Conceitos - .NET Framework versus .NET Core - Macoratti
ASP .NET Core - Conceitos Básicos - Macoratti.net
ASP .NET Core MVC - CRUD básico com ADO .NET - Macoratti
ASP .NET Core - Implementando a segurança com ... - Macoratti.net
ASP .NET Core - Apresentando Razor Pages - Macoratti