
Recentemente iniciei uma série sobre as novidades do ASP.NET Core 2.1 (que ainda se encontra em Preview). O primeiro artigo abordou o suporte a HTTPS, característica esta, que será default nesta nova versão da plataforma Web da Microsoft:
Neste novo artigo, abordo o uso do tipo genérico ActionResult<T>, estrutura concebida com o objetivo de simplificar a codificação de instruções de retorno em APIs. Em um artigo anterior sobre APIs REST no ASP.NET Core 2.0, detalhei o uso de mensagens de erro customizadas em APIs REST:
A listagem a seguir retoma o exemplo envolvendo a classe CatalogoController:
- Analisando a estrutura destes métodos é possível notar que o retorno dos mesmos é uma instância baseada na interface IActionResult (namespace Microsoft.AspNetCore.Mvc);
- Ao informar um código válido e um item for encontrado, o retorno destas construções será uma instância do tipo ObjectResult (namespace Microsoft.AspNetCore.Mvc) contendo um produto ou serviço;
- Se tratando de um código inválido ou que corresponda a um item não existente, será então acionado o método NotFound (namespace Microsoft.AspNetCore.Mvc). Como resultado, teremos a geração de um erro do tipo 404 (indicativo de um recurso não encontrado).
using Microsoft.AspNetCore.Mvc;
namespace APICatalogo.Controllers
{
[Route("api/[controller]")]
public class CatalogoController : Controller
{
private CatalogoContext _contexto;
public CatalogoController(CatalogoContext context)
{
_contexto = context;
}
[HttpGet("produtos/{codigo}")]
public IActionResult GetProduto(string codigo)
{
Produto prod = null;
if (codigo.StartsWith("PROD"))
prod = _contexto.ObterItem<Produto>(codigo);
if (prod != null)
return new ObjectResult(prod);
else
{
return NotFound(
"Código de produto inválido ou item inexistente.");
}
}
[HttpGet("servicos/{codigo}")]
public IActionResult GetServico(string codigo)
{
Servico serv = null;
if (codigo.StartsWith("SERV"))
serv = _contexto.ObterItem<Servico>(codigo);
if (serv != null)
return new ObjectResult(serv);
else
{
return NotFound(
new
{
Mensagem = "Código de serviço inválido ou item inexistente.",
Erro = true
});
}
}
}
}
Com ActionResult<T> podemos agora simplificar tal implementação, dispensando assim, o uso da classe ObjectResult (o retorno, neste caso, será a própria instância do tipo indicado por T em ActionResult<T>):
using Microsoft.AspNetCore.Mvc;
namespace APICatalogo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CatalogoController : ControllerBase
{
private CatalogoContext _contexto;
public CatalogoController(CatalogoContext context)
{
_contexto = context;
}
[HttpGet("produtos/{codigo}")]
public ActionResult<Produto> GetProduto(string codigo)
{
Produto prod = null;
if (codigo.StartsWith("PROD"))
prod = _contexto.ObterItem<Produto>(codigo);
if (prod != null)
return prod;
else
{
return NotFound(
"Código de produto inválido ou item inexistente.");
}
}
[HttpGet("servicos/{codigo}")]
public ActionResult<Servico> GetServico(string codigo)
{
Servico serv = null;
if (codigo.StartsWith("SERV"))
serv = _contexto.ObterItem<Servico>(codigo);
if (serv != null)
return serv;
else
{
return NotFound(
new
{
Mensagem = "Código de serviço inválido ou item inexistente.",
Erro = true
});
}
}
}
}
É possível observar nas imagens a seguir os retornos produzidos pela Action GetProduto:


E pela Action GetServico:






