Cómo omitir métodos de la documentación de Swagger en WebAPI usando Swashbuckle

135

Tengo una aplicación C # ASP.NET WebAPI con documentación de API que se genera automáticamente usando Swashbuckle . Quiero poder omitir ciertos métodos de la documentación pero parece que no puedo resolver cómo decirle a Swagger que no los incluya en la salida de la interfaz de usuario de Swagger.

Siento que tiene algo que ver con agregar un modelo o filtro de esquema, pero no es obvio qué hacer y la documentación solo parece proporcionar ejemplos de cómo modificar la salida de un método, no eliminarlo completamente de la salida.

Gracias por adelantado.

SteveWilkinson
fuente

Respuestas:

337

Puede agregar el siguiente atributo a Controladores y Acciones para excluirlos de la documentación generada: [ApiExplorerSettings(IgnoreApi = true)]

mikesigs
fuente
12
Funcionó muy bien, esta debería ser la respuesta
JohnC
44
¿Hay alguna manera de hacer esto mediante programación? Quiero exponer una API en algunos entornos pero no en otros, de acuerdo con una configuración.
Paul Kienitz
@SyaifulNizamYahya No estoy seguro. Tal vez [JsonIgnore]?
mikesigs
@mikesigs Sí [JsonIgnore] funciona. Desafortunadamente, prohíbe la serialización.
Syaiful Nizam Yahya
44
Documentación de Swashbuckle: Omitir operaciones arbitrarias
spottedmahn
17

Alguien publicó la solución en github, así que voy a pegarla aquí. Todos los créditos van a él. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

Crear primero una clase de atributo

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

Luego cree una clase de filtro de documentos

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

Luego, en la clase Swagger Config, agregue ese filtro de documentos

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

        config
             .EnableSwagger(c =>
                {
                    ...                       
                    c.DocumentFilter<HideInDocsFilter>();
                    ...
                })
            .EnableSwaggerUi(c =>
                {
                    ...
                });
    }
}

El último paso es agregar el atributo [HideInDocsAttribute] en el Controlador o Método que no desea que Swashbuckle genere documentación.

Paulo Pozeti
fuente
1
Creo que RemoveRoute podría ser el droide que estoy buscando.
Paul Kienitz
13

Puede eliminar las "operaciones" del documento swagger después de que se haya generado con un filtro de documentos; simplemente establezca el verbo en null(aunque también puede haber otras formas de hacerlo)

El siguiente ejemplo solo permite GETverbos, y está tomado de este problema .

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

y en tu configuración de swagger:

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

    conf.DocumentFilter<RemoveVerbsFilter>();
});
Dave Transom
fuente
1
Tenga en cuenta: esto no eliminará la ruta incluso si descomenta path.get = null;, como resultado, esas rutas aún se incluirán en el archivo Swagger, pero solo sin los detalles. Sería mejor incluirlo ApiExplorerSettingsAttributeen su respuesta como lo mencionó en su respuesta original en GitHub. El uso de ApiExplorerSettings también puede evitar que se agregue información de tipo a la schemeslista del archivo Swagger .
JBert
7

Preferiría eliminar completamente las entradas del diccionario para elementos de ruta:

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

foreach (var item in pathsToRemove)
{
    swaggerDoc.Paths.Remove(item.Key);
}

Con este enfoque, no obtendría elementos "vacíos" en la definición generada de swagger.json.

Denis Biondic
fuente
3

Hacer un filtro

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

Hacer un atributo

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

Aplicar en startup.cs

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

Agregue el atributo [SwaggerTag] a los métodos y controladores que desea incluir en Swagger JSON

Rowan Stringer
fuente
Dulce. Enfoque apropiado y gracias por compartir el sln.
Vedran Mandić
2

Puede ayudar a alguien, pero durante el desarrollo (depuración) nos gusta exponer controladores y / o acciones completos y luego ocultarlos durante la producción (compilación de lanzamiento)

#if DEBUG
    [ApiExplorerSettings(IgnoreApi = false)]
#else
    [ApiExplorerSettings(IgnoreApi = true)]
#endif  
Soeren Pedersen
fuente
1

Basado en la respuesta de @spottedmahns . Mi tarea era viceversa. Mostrar solo los que están permitidos.

Marcos: .NetCore 2.1; Swagger: 3.0.0

Atributo agregado

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

E implementar IDocumentFilter personalizado

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

Código de ConfigureServices :

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

    services.AddSwaggerGen(c =>
    {
        // other configurations
        c.DocumentFilter<ShowInSwaggerFilter>();
    });
}
aleha
fuente
Gracias Aleha Este enfoque realmente funciona bien para SwashBuckle.OData donde ApiExplorerSettingsAttribute no funciona.
Prasad Korhale
1

agregue una línea 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);
}
    }
}
Vikramraj
fuente
0

Agregue esto encima de los métodos que desea omitir.

[ApiExplorerSettings(IgnoreApi=true)]
Mridusmita Deka
fuente