Atributos personalizados na API .NET 6 Core

· 3 min de leitura

Atributos personalizados são realmente uma boa coisa para usar, comecei a usá-los muito recentemente, porque eles me permitem criar um único deles e reutilizá-los no controlador, na classe ou no próprio método.

Eles realmente ajudam quando você deseja fazer algumas tarefas de segurança, como verificar cabeçalhos ou verificar o valor de um parâmetro que você definitivamente precisa.

No meu caso vamos utilizá-lo em um projeto de API .NET Core, onde vamos verificar se todas as solicitações contêm um determinado cabeçalho.

HeaderCheckAttribute

Então, depois de criarmos nossa API .NET Core, vamos criar uma pasta para armazenar nossas coisas, porque gostamos de usar pastas.

E então vamos adicionar a lógica à nossa classe HeaderCheckAttribute.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace DotNet6CustomAttribute.Attributes
{
    public class HeaderCheckAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            // Get all headers
            var headers = context.HttpContext.Request.Headers;

            // Check if headers has x-dotnet-6-custom-attribute
            if (!headers.ContainsKey("x-dotnet-6-custom-attribute"))
            {
                context.Result = new BadRequestObjectResult("The header x-dotnet-6-custom-attribute is missing");
            }
            else if (string.IsNullOrEmpty(headers["x-dotnet-6-custom-attribute"]))
            {
                context.Result = new BadRequestObjectResult("The header x-dotnet-6-custom-attribute can't be null or empty");
            }

            base.OnActionExecuting(context);
        }
    }
}

Basicamente a lógica é: primeiro ele verifica se há um cabeçalho com a chave x-dotnet-6-custom-attribute e se estiver lá, verifica se possui valores.

Se ambas as expressões forem verdadeiras, ele retornará um BadRequestObjectResult com uma determinada mensagem.

Adicionando-o ao controlador

Podemos adicionar essa lógica a vários lugares, podemos adicioná-la diretamente a todo o controlador, ou podemos adicioná-la a alguns dos métodos, vamos adicioná-la primeiro aos métodos e depois a todo o controlador.

Então vamos decorar a classe WeatherForecastController com eles.

using DotNet6CustomAttribute.Attributes;
using Microsoft.AspNetCore.Mvc;

namespace DotNet6CustomAttribute.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        [Route("GetWeatherForecastWithCheck")]
        [HeaderCheckAttribute]
        public IEnumerable<WeatherForecast> GetWithCheck()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }

        [HttpGet]
        [Route("GetWeatherForecastWithoutCheck")]
        public IEnumerable<WeatherForecast> GetWithoutCheck()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

Vamos executar o projeto!

Temos 2 funções lá: GetWeatherForecastWithCheck e GetWeatherForecastWithoutCheck, uma delas irá falhar e a outra não, mas vamos dar uma olhada no Swagger!

Como você pode ver um deles retorna um erro 400 com nossa mensagem, e o outro retorna os valores, agora para testar isso completamente, vamos executar o Postman e adicionar um cabeçalho para que também vejamos os dados usando GetWeatherForecastWithCheck.

#Carteiro

Agora rodando no Postman, adicionamos o cabeçalho e vemos que a mensagem de erro mudou, pois agora fornecemos o cabeçalho, mas não há valor para ele

Se adicionarmos um valor a ele, finalmente obteremos os valores!

#É isso

Bem, é isso! Muito simples, certo? Bem, agora você sabe como criar um atributo e atribuí-lo a métodos e controladores!

Divirta-se com eles!

Código

Todo esse projeto está no Github e você pode encontrá-lo aqui!

Se você tiver qualquer problema ou dúvida, sinta-se à vontade para entrar em contato comigo em qualquer mídia social em @emimontesdeoca (no Twitter é na verdade @emimontesdeocaa com dois aa no final). Você também pode encontrar a maioria das minhas redes sociais no cabeçalho do blog.

Espero que você tenha gostado da postagem! Cia!