.NET 6 Core API 上的自定义属性

· 2 分钟阅读

自定义属性确实是一件很好用的东西,我最近开始使用它们,因为它们允许我创建其中的单个属性并在控制器、类或方法本身上重用它们。

当您想要执行一些安全操作(例如检查标头或检查您确实需要的参数的值)时,它们确实很有帮助。

就我而言,我们将在 .NET Core API 项目中使用它,我们将在其中检查所有请求是否包含特定标头。

标头检查属性

因此,在创建了很酷的 .NET Core API 之后,让我们创建一个文件夹来存储我们的内容,因为我们喜欢使用文件夹。

然后我们将逻辑添加到我们的 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);
        }
    }
}

基本上的逻辑是,首先它检查带有键 x-dotnet-6-custom-attribute 的标头,如果存在,它检查它是否有值。

如果这两个表达式都为 true,它将返回带有特定消息的 BadRequestObjectResult

将其添加到控制器中

我们可以将这个逻辑添加到多个地方,我们可以直接添加到整个控制器,也可以将它添加到某些方法中,我们将首先将其添加到方法中,然后添加到整个控制器中。

因此,让我们用它们来装饰 WeatherForecastController 类。

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();
        }
    }
}

让我们运行该项目吧!

我们有 2 个函数:GetWeatherForecastWithCheckGetWeatherForecastWithoutCheck,其中一个会失败,其他不会,但让我们在 Swagger 上检查一下!

正如您所看到的,其中一个返回了我们的消息的 400 错误,另一个返回了值,现在为了充分测试这一点,让我们运行 Postman 并添加一个标头,以便我们还可以使用 GetWeatherForecastWithCheck 看到数据。

邮递员

现在在 Postman 上运行,我们添加标头,我们看到错误消息已更改,因为现在我们确实提供了标头,但它没有任何价值

如果我们给它添加一个值,我们最终就得到了值!

就是这样

好吧,就是这样!很简单吧?现在您知道如何创建属性并将其分配给方法和控制器!

和他们一起玩得开心!

代码

整个项目都在 Github 上,您可以在此处找到它!

如果您有任何问题或疑问,请随时在任何社交媒体上与我联系:@emimontesdeoca(在 Twitter 中实际上是 @emimontesdeocaa,末尾有两个 aa)。您还可以在博客标题上找到我的大部分社交活动。

希望你喜欢这篇文章!呀!