Atributos personalizados en .NET 6 Core API
Los atributos personalizados son realmente buenos de usar, comencé a usarlos hace muy poco tiempo, porque me permiten crear uno solo de ellos y reutilizarlos en el controlador, la clase o el método en sí.
Realmente ayudan cuando quieres hacer algunas cosas de seguridad como verificar encabezados o verificar el valor de un parámetro que definitivamente necesitas.
En mi caso, lo usaremos en un proyecto API de .NET Core, donde verificaremos si todas las solicitudes contienen un encabezado determinado.
EncabezadoCheckAttribute
Entonces, después de crear nuestra excelente API .NET Core, creemos una carpeta para almacenar nuestras cosas, porque nos gusta usar carpetas.

Y luego vamos a agregar la lógica a nuestra clase 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);
}
}
}
Básicamente, la lógica es que primero busca un encabezado con la clave x-dotnet-6-custom-attribute y, si está allí, verifica si tiene valores.
Si ambas expresiones son verdaderas, devolverá un BadRequestObjectResult con un mensaje determinado.
Agregándolo al controlador
Podemos agregar esta lógica a varios lugares, podemos agregarla directamente a todo el controlador, o podemos agregarla a algunos de los métodos, primero la agregaremos a los métodos y luego a todo el controlador.
Así que decoremos la clase WeatherForecastController con ellos.
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 a ejecutar el proyecto!

Tenemos 2 funciones ahí: GetWeatherForecastWithCheck y GetWeatherForecastWithoutCheck, una de ellas fallará y la otra no, ¡pero veámoslo en Swagger!

Como puede ver, uno de ellos devuelve un error 400 con nuestro mensaje y el otro devuelve los valores. Ahora, para probar esto completamente, ejecutemos Postman y agreguemos un encabezado para que también veamos los datos usando GetWeatherForecastWithCheck.
cartero
Ahora, ejecutando Postman, agregamos el encabezado y vemos que el mensaje de error ha cambiado, ya que ahora proporcionamos el encabezado pero no tiene ningún valor.

Si le agregamos un valor, ¡finalmente obtenemos los valores!

Eso es todo
¡Pues eso es todo! Bastante simple ¿verdad? ¡Bueno, ahora sabes cómo crear un atributo y asignarlo a métodos y controladores!
¡Diviértete con ellos!
Código
¡Este proyecto completo está en Github y puedes encontrarlo aquí!
Si tienes algún problema o pregunta, no dudes en contactarme en cualquier red social en @emimontesdeoca (en Twitter en realidad es @emimontesdeocaa con dos aa al final). También puedes encontrar la mayoría de mis redes sociales en el encabezado del blog.
Espero que os haya gustado el post! ¡Cya!