隐藏Swagger(Swashbuckle)中的参数

5

我有一个C# .NET 5.0 ASP.NET Core Web API应用程序,选择了“启用OpenAPI支持”。我想要隐藏下面示例中显示在Swagger页面上的可选参数。我找到了许多关于隐藏属性或控制器的帖子,但这些解决方案似乎都不适用于给定代码中的参数:

[HttpGet]
[Route("search")]
[Authorize]
public async Task<IActionResult> Search(string query, string optional = "")
{
   return OK();
}
1个回答

13

您可以创建一个自定义属性和继承自Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter的操作筛选器,以从swagger.json生成中排除所需的参数。

public class OpenApiParameterIgnoreAttribute : System.Attribute
{
}

public class OpenApiParameterIgnoreFilter : Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter
{
    public void Apply(Microsoft.OpenApi.Models.OpenApiOperation operation, Swashbuckle.AspNetCore.SwaggerGen.OperationFilterContext context)
    {
        if (operation == null || context == null || context.ApiDescription?.ParameterDescriptions == null)
            return;

        var parametersToHide = context.ApiDescription.ParameterDescriptions
            .Where(parameterDescription => ParameterHasIgnoreAttribute(parameterDescription))
            .ToList();

        if (parametersToHide.Count == 0)
            return;

        foreach (var parameterToHide in parametersToHide)
        {
            var parameter = operation.Parameters.FirstOrDefault(parameter => string.Equals(parameter.Name, parameterToHide.Name, System.StringComparison.Ordinal));
            if (parameter != null)
                operation.Parameters.Remove(parameter);
        }
    }

    private static bool ParameterHasIgnoreAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterDescription parameterDescription)
    {
        if (parameterDescription.ModelMetadata is Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata metadata)
        {
            return metadata.Attributes.ParameterAttributes.Any(attribute => attribute.GetType() == typeof(OpenApiParameterIgnoreAttribute));
        }

        return false;
    }
}

将它放在您的控制器参数中。

[HttpGet]
[Route("search")]
[Authorize]
public async Task<IActionResult> Search(string query, [OpenApiParameterIgnore] string optional = "")
{
    return Ok();
}

然后在 Status.cs 中配置它。

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API Title", Version = "v1" });
        c.OperationFilter<OpenApiParameterIgnoreFilter>();
    });

感谢您包含“将其放入控制器参数”部分!我不理解(仍然不理解)OpenApiParameterIgnore在您提供的代码中的任何其他引用方式。我猜它来自OpenApiParameterIgnoreAttribute,并且Attribute部分是暗示的? - paulguy
是的,Attribute后缀由编译器隐含。根据命名规范,Microsoft建议以基类的名称结束自定义类名。https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces?redirectedfrom=MSDN - Ricardo Yanez
忽略过滤器在属性直接位于方法参数列表中时有效,但当参数是一个复合类型且属性位于应该被忽略的复合类型内部时,则无法起作用。为使其适用于该情况,代码需要做出哪些改变? - M. Koch
1
如果将 metadata.Attributes.ParameterAttributes 更改为 metadata.Attributes.Attributes,它也可以在类内部工作。 - M. Koch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接