How to omit methods from Swagger documentation on WebAPI using Swashbuckle

前端 未结 10 796
不思量自难忘°
不思量自难忘° 2020-11-30 19:38

I have a C# ASP.NET WebAPI application with API documentation being automatically generated using Swashbuckle. I want to be able to omit certain methods fr

相关标签:
10条回答
  • 2020-11-30 20:13

    Make a filter

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

    Make an attribute

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class SwaggerTagAttribute : Attribute
    {
    }
    

    Apply in startup.cs

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

    Add [SwaggerTag] attribute to methods and controllers you want to include in Swagger JSON

    0 讨论(0)
  • 2020-11-30 20:15

    Add this on top of your Methods that you want to omit-

    [ApiExplorerSettings(IgnoreApi=true)]
    
    0 讨论(0)
  • 2020-11-30 20:22

    May help somebody but during development (debugging) we like to expose whole Controllers and/or Actions and then hide these during production (release build)

    #if DEBUG
        [ApiExplorerSettings(IgnoreApi = false)]
    #else
        [ApiExplorerSettings(IgnoreApi = true)]
    #endif  
    
    0 讨论(0)
  • 2020-11-30 20:28

    Someone posted the solution on github so I'm going to paste it here. All credits goes to him. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

    Create first an Attribute class

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class HideInDocsAttribute : Attribute
    {
    }
    

    Then create a Document Filter class

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

    Then in Swagger Config class, add that document filter

    public class SwaggerConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var thisAssembly = typeof(SwaggerConfig).Assembly;
    
            config
                 .EnableSwagger(c =>
                    {
                        ...                       
                        c.DocumentFilter<HideInDocsFilter>();
                        ...
                    })
                .EnableSwaggerUi(c =>
                    {
                        ...
                    });
        }
    }
    

    Last step is to add [HideInDocsAttribute] attribute on the Controller or Method you don't want Swashbuckle to generate documentation.

    0 讨论(0)
  • 2020-11-30 20:28

    add one line SwaggerConfig c.DocumentFilter();

    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);
    }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 20:29

    Based on @spottedmahns answer. My task was vice versa. Show only those that are allowed.

    Frameworks: .NetCore 2.1; Swagger: 3.0.0

    Added attribute

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class ShowInSwaggerAttribute : Attribute
    {
    }
    

    And implement custom IDocumentFilter

    public class ShowInSwaggerFilter : IDocumentFilter
    {
        public void Apply(SwaggerDocument 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 pathItem = swaggerDoc.Paths[key];
                    if(pathItem == null)
                        continue;
    
                    switch (contextApiDescription.HttpMethod.ToUpper())
                    {
                        case "GET":
                            pathItem.Get = null;
                            break;
                        case "POST":
                            pathItem.Post = null;
                            break;
                        case "PUT":
                            pathItem.Put = null;
                            break;
                        case "DELETE":
                            pathItem.Delete = null;
                            break;
                    }
    
                    if (pathItem.Get == null  // ignore other methods
                        && pathItem.Post == null 
                        && pathItem.Put == null 
                        && pathItem.Delete == null)
                        swaggerDoc.Paths.Remove(key);
                }
            }
        }
    }
    

    ConfigureServices code:

    public void ConfigureServices(IServiceCollection services)
    {
         // other code
    
        services.AddSwaggerGen(c =>
        {
            // other configurations
            c.DocumentFilter<ShowInSwaggerFilter>();
        });
    }
    
    0 讨论(0)
提交回复
热议问题