如何在 .NET 6 中注册动作过滤器

How to register action filter in .NET 6

我有这个验证过滤器 class。

public class ValidationFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        if (!context.ModelState.IsValid)
        {
            var errorsInModelState = context.ModelState
                .Where(x => x.Value?.Errors.Count > 0)
                .ToDictionary(kvp => kvp.Key, kvp => kvp.Value?.Errors.Select(x => x.ErrorMessage)).ToArray();

            var errorResponse = new ErrorResponse();

            foreach (var error in errorsInModelState)
            {
                foreach (var subError in error.Value)
                {
                    var errorModel = new Error
                    {
                        FieldName = error.Key,
                        Message = subError
                    };

                    errorResponse.Errors.Add(errorModel);
                }
            }

            context.Result = new BadRequestObjectResult(errorResponse);
            return;
        }
        await next();
    }
}

在ASP.NET5中,我们添加如下的ValidationFilter

        services
            .AddMvc(options =>
            {
                options.EnableEndpointRouting = false;
                options.Filters.Add<ValidationFilter>();
            })
            .AddFluentValidation(mvcConfiguration => mvcConfiguration.RegisterValidatorsFromAssemblyContaining<Startup>())
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

如何在 .NET 6 中将其添加到 Program.cs

您可以定义一个继承自 ActionFilterAttribute 的 class 根据以下示例代码将 header 添加到响应中:

public class ResponseHeaderAttribute : ActionFilterAttribute
{
    private readonly string _name;
    private readonly string _value;

    public ResponseHeaderAttribute(string name, string value) =>
        (_name, _value) = (name, value);

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add(_name, _value);

        base.OnResultExecuting(context);
    }
}

然后您可以在 Program.cs 文件中添加过滤器(基于 dot net 6 新控制台模板):

builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<ResponseHeaderAttribute>();
});

现在您可以在您的控制器中使用它,例如:

[ResponseHeader("my-filter", "which has the value")]
public IActionResult DoSomething() =>
    Content("I'm trying to do something");

在 .Net6 中,我们使用 builder.Services.AddControllersWithViews() 而不是 services.AddMvc()。所以你可以这样设置:

builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<ValidationFilter>();
});

更多关于.NET 6新配置可以参考这个link