如何使用Swashbuckle在WebAPI上省略Swagger文档中的方法

Ste*_*son 110 .net c# asp.net swagger

我有一个C#ASP.NET WebAPI应用程序,其中包含使用Swashbuckle自动生成的API文档.我希望能够从文档中省略某些方法,但我似乎无法弄清楚如何告诉Swagger不要将它们包含在Swagger UI输出中.

我觉得它与添加模型或模式过滤器有关,但它不明显该做什么,文档似乎只提供了如何修改方法的输出的示例,而不是从输出中完全删除它.

提前致谢.

mik*_*igs 253

您可以将以下属性添加到控制器和操作,以从生成的文档中排除它们: [ApiExplorerSettings(IgnoreApi = true)]

  • 工作得很好,这应该是答案 (8认同)
  • 有没有办法以编程方式做到这一点?根据配置设置,我想在某些环境中公开 API,但不在其他环境中公开。 (8认同)
  • Swashbuckle文档:[省略任意操作](https://github.com/domaindrivendev/Swashbuckle.AspNetCore#omit-arbitrary-operations) (4认同)
  • System.Web.Http.Description.ApiExplorerSettings、System.Web.Http (2认同)

Dav*_*som 13

在使用文档过滤器生成后,您可以从swagger文档中删除"操作" - 只需将动词设置为null(但是,可能还有其他方法可以执行此操作)

以下示例仅允许使用GET动词 - 并且取自此问题.

class RemoveVerbsFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (PathItem path in swaggerDoc.paths.Values)
        {
            path.delete = null;
            //path.get = null; // leaving GET in
            path.head = null;
            path.options = null;
            path.patch = null;
            path.post = null;
            path.put = null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并在你的招摇配置:

...EnableSwagger(conf => 
{
    // ...

    conf.DocumentFilter<RemoveVerbsFilter>();
});
Run Code Online (Sandbox Code Playgroud)

  • 请注意:即使您取消注释 `path.get = null;`,这也不会删除路径 - 因此这些路径仍将包含在 Swagger 文件中,但只是没有详细信息。正如您在 GitHub 上的原始回复中提到的那样,最好在您的答案中包含“ApiExplorerSettingsAttribute”。使用 ApiExplorerSettings 还可以避免将类型信息添加到 Swagger 文件的“schemes”列表中。 (2认同)

小智 12

有人在github上发布了解决方案,所以我要把它粘贴到这里.所有学分归他所有.https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

首先创建一个Attribute类

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class HideInDocsAttribute : Attribute
{
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个文档过滤器类

public class HideInDocsFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (var apiDescription in apiExplorer.ApiDescriptions)
        {
            if (!apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<HideInDocsAttribute>().Any() && !apiDescription.ActionDescriptor.GetCustomAttributes<HideInDocsAttribute>().Any()) continue;
            var route = "/" + apiDescription.Route.RouteTemplate.TrimEnd('/');
            swaggerDoc.paths.Remove(route);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在Swagger Config类中添加该文档过滤器

public class SwaggerConfig
{
    public static void Register(HttpConfiguration config)
    {
        var thisAssembly = typeof(SwaggerConfig).Assembly;

        config
             .EnableSwagger(c =>
                {
                    ...                       
                    c.DocumentFilter<HideInDocsFilter>();
                    ...
                })
            .EnableSwaggerUi(c =>
                {
                    ...
                });
    }
}
Run Code Online (Sandbox Code Playgroud)

最后一步是在Controller或Method上添加[HideInDocsAttribute]属性,不要让Swashbuckle生成文档.

  • 我认为 RemoveRoute 可能是我正在寻找的机器人。 (2认同)

小智 8

可能对某人有所帮助,但在开发(调试)期间,我们喜欢公开整个控制器和/或操作,然后在生产(发布版本)期间隐藏它们

#if DEBUG
    [ApiExplorerSettings(IgnoreApi = false)]
#else
    [ApiExplorerSettings(IgnoreApi = true)]
#endif  
Run Code Online (Sandbox Code Playgroud)


Gav*_*ide 8

像@aleha一样,我想默认排除,这样我就不会意外暴露端点(默认安全),但使用的是使用OpenApiDocument的较新版本的Swagger。

创建 ShowInSwagger 属性

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class ShowInSwaggerAttribute : Attribute
{}
Run Code Online (Sandbox Code Playgroud)

然后创建文档过滤器

using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;
using System;
using System.Linq;
using TLS.Common.Attributes;

namespace TLS.Common.Filters
{
    public class ShowInSwaggerFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            foreach (var contextApiDescription in context.ApiDescriptions)
            {
                var actionDescriptor = (ControllerActionDescriptor)contextApiDescription.ActionDescriptor;

                if (actionDescriptor.ControllerTypeInfo.GetCustomAttributes<ShowInSwaggerAttribute>().Any() ||
                    actionDescriptor.MethodInfo.GetCustomAttributes<ShowInSwaggerAttribute>().Any())
                {
                    continue;
                }
                else
                {
                    var key = "/" + contextApiDescription.RelativePath.TrimEnd('/');
                    var operation = (OperationType)Enum.Parse(typeof(OperationType), contextApiDescription.HttpMethod, true);

                    swaggerDoc.Paths[key].Operations.Remove(operation);

                    // drop the entire route of there are no operations left
                    if (!swaggerDoc.Paths[key].Operations.Any())
                    {
                        swaggerDoc.Paths.Remove(key);
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的startup.cs或ConfigureServices中:

public void ConfigureServices(IServiceCollection services)
{
     // other code

    services.AddSwaggerGen(c =>
    {
        c.DocumentFilter<ShowInSwaggerFilter>();
        // other config
    });
}
Run Code Online (Sandbox Code Playgroud)


Den*_*dic 7

我更愿意完全删除路径项的字典条目:

var pathsToRemove = swaggerDoc.Paths
                .Where(pathItem => !pathItem.Key.Contains("api/"))
                .ToList();

foreach (var item in pathsToRemove)
{
    swaggerDoc.Paths.Remove(item.Key);
}
Run Code Online (Sandbox Code Playgroud)

使用这种方法,您不会在生成的 swagger.json 定义中获得“空”项。


小智 7

做一个过滤器

public class SwaggerTagFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach(var contextApiDescription in context.ApiDescriptions)
        {
            var actionDescriptor = (ControllerActionDescriptor)contextApiDescription.ActionDescriptor;
            
            if(!actionDescriptor.ControllerTypeInfo.GetCustomAttributes<SwaggerTagAttribute>().Any() && 
               !actionDescriptor.MethodInfo.GetCustomAttributes<SwaggerTagAttribute>().Any())
            {
                var key = "/" + contextApiDescription.RelativePath.TrimEnd('/');
                swaggerDoc.Paths.Remove(key);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

做一个属性

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class SwaggerTagAttribute : Attribute
{
}
Run Code Online (Sandbox Code Playgroud)

在startup.cs中申请

services.AddSwaggerGen(c => {
    c.SwaggerDoc(1, new Info { Title = "API_NAME", Version = "API_VERSION" });
    c.DocumentFilter<SwaggerTagFilter>(); // [SwaggerTag]
});
Run Code Online (Sandbox Code Playgroud)

将 [SwaggerTag] 属性添加到要包含在 Swagger JSON 中的方法和控制器


小智 6

如果您使用的是最小 API,您可以使用:

app.MapGet("/hello", () => "Hello World!").ExcludeFromDescription();
Run Code Online (Sandbox Code Playgroud)


小智 5

向 SwaggerConfig 添加一行

c.DocumentFilter<HideInDocsFilter>();

...

public class HideInDocsFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    { 
        var pathsToRemove = swaggerDoc.Paths
            .Where(pathItem => !pathItem.Key.Contains("api/"))
            .ToList();
    
        foreach (var item in pathsToRemove)
        {
            swaggerDoc.Paths.Remove(item.Key);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)