asp.net ActionFilterAttribute已停止使用IOperationFilter

jfewjypa  于 2023-08-08  发布在  .NET
关注(0)|答案(1)|浏览(94)

我已经创建了一个ActionFilterAttribute,但它不适用于Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter

我自定义的必选项头属性:

using Microsoft.AspNetCore.Mvc.Filters;

namespace MyProject.Filters;

public class MandatoryHeaderAttribute : ActionFilterAttribute
{
    private readonly string _headerName;

    public MandatoryHeaderAttribute(string headerName)
    {
        _headerName = headerName;
    }

    public string HeaderName => _headerName;

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        context.HttpContext.Request.Headers.TryGetValue(HeaderName, out var headerValue);
        if (string.IsNullOrEmpty(headerValue))
        {
            throw new Exception($"{HeaderName} is a mandatory header.");
        }

        base.OnActionExecuting(context);
    }
}

字符串

我的操作过滤器,动态添加必选表头:

using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace MyProject.Filters;

public class MandatoryHeaderOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var actionDescriptor = context.ApiDescription.ActionDescriptor as ControllerActionDescriptor;
        if (actionDescriptor == null)
        {
            return;
        }

        operation.Parameters ??= new List<OpenApiParameter>();

        var mandatoryHeaders = actionDescriptor.MethodInfo.GetCustomAttributes(true).OfType<MandatoryHeaderAttribute>();

        foreach (var header in mandatoryHeaders)
        {
            operation.Parameters.Add(new OpenApiParameter
            {
                Name = header.HeaderName,
                In = ParameterLocation.Header,
                Required = true
            });
        }
    }
}


我已经尝试在启动时手动添加ActionFilterAttribute,但它仍然不起作用,一旦我删除了SwaggerOperationFilter,它就恢复工作了

启动

builder.Services.AddSwaggerGen(swagger =>
{
    swagger.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "MyProject",
        Description = "MyProject description",
        Version = "v1"
    });
    swagger.CustomSchemaIds(type => type.ToString());
    swagger.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "swagger.xml"));
    swagger.EnableAnnotations();
    swagger.OperationFilter<MandatoryHeaderOperationFilter>();
});

oxf4rvwz

oxf4rvwz1#

使用SwaggerGen时,ActionFilterAttribute不会自动应用于操作。MandatoryHeaderAttribute将在正常运行时执行操作时按预期工作,但在SwaggerGen生成OpenAPI规范时不会执行。
手动将MandatoryHeaderAttribute应用于操作:
在控制器中,将MandatoryHeaderAttribute应用于需要强制标头的操作。

[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
    [HttpGet]
    [MandatoryHeader("X-Custom-Header")] // Apply the attribute here
    public IActionResult Get()
    {
        // Your action code here
    }
}

字符串
为了避免重复头定义,您还可以修改MandatoryHeaderOperationFilter,以查找动作上的MandatoryHeaderAttribute,并相应地生成OpenAPI参数。这样,您就不必手动将属性应用于操作,并保持逻辑集中化。

public class MandatoryHeaderOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var mandatoryHeaders = context.MethodInfo.GetCustomAttributes(true).OfType<MandatoryHeaderAttribute>();

        foreach (var header in mandatoryHeaders)
        {
            if (operation.Parameters == null)
            {
                operation.Parameters = new List<OpenApiParameter>();
            }

            // Check if the parameter with the same name already exists to avoid duplication
            if (!operation.Parameters.Any(p => p.Name == header.HeaderName))
            {
                operation.Parameters.Add(new OpenApiParameter
                {
                    Name = header.HeaderName,
                    In = ParameterLocation.Header,
                    Required = true
                });
            }
        }
    }
}


通过此修改,MandatoryHeaderOperationFilter将确保仅为操作上使用的每个唯一MandatoryHeaderAttribute添加一次参数。
现在,当您将MandatoryHeaderAttribute应用于操作时,它将在运行时与SwaggerGen一起按预期工作。该属性将被触发,并且每当通过Swagger或直接调用端点时,将执行验证。

相关问题