Come omettere i metodi dalla documentazione di Swagger su WebAPI usando Swashbuckle


135

Ho un'applicazione WebAPI ASP.NET C # con la documentazione API generata automaticamente tramite Swashbuckle . Voglio essere in grado di omettere determinati metodi dalla documentazione ma non riesco a capire come dire a Swagger di non includerli nell'output dell'interfaccia utente di Swagger.

Sento che ha a che fare con l' aggiunta di un filtro modello o schema ma non è ovvio cosa fare e la documentazione sembra fornire solo esempi di come modificare l'output per un metodo, non rimuoverlo completamente dall'output.

Grazie in anticipo.

Risposte:


337

È possibile aggiungere il seguente attributo ai controller e alle azioni per escluderli dalla documentazione generata: [ApiExplorerSettings(IgnoreApi = true)]


12
Ha funzionato alla grande, questa dovrebbe essere la risposta
JohnC

4
C'è un modo per farlo programmaticamente? Voglio esporre un'API in alcuni ambienti ma non in altri, secondo un'impostazione di configurazione.
Paul Kienitz,

@SyaifulNizamYahya Non sono sicuro. Forse [JsonIgnore]?
Mikesigs,

@mikesigs Sì [JsonIgnore] funziona. Sfortunatamente, proibisce la serializzazione.
Syaiful Nizam Yahya,

4
Documentazione di Swashbuckle: Omit Arbitrary Operations
spottedmahn,

17

Qualcuno ha pubblicato la soluzione su github, quindi ho intenzione di incollarla qui. Tutti i crediti vanno a lui. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

Creare prima una classe di attributi

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

Quindi creare una classe Filtro documenti

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

Quindi, nella classe Swagger Config, aggiungi quel filtro documenti

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

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

L'ultimo passaggio è aggiungere l'attributo [HideInDocsAttribute] sul controller o sul metodo che non si desidera che Swashbuckle generi documentazione.


1
Penso che RemoveRoute potrebbe essere il droide che sto cercando.
Paul Kienitz,

13

Puoi rimuovere "operazioni" dal documento spavalderia dopo che è stato generato con un filtro documento - imposta semplicemente il verbo su null(sebbene, ci potrebbero essere anche altri modi per farlo)

L'esempio seguente consente solo i GETverbi ed è tratto da questo 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;
        }
    }
}

e nella tua configurazione spavalderia:

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

    conf.DocumentFilter<RemoveVerbsFilter>();
});

1
Nota: questo non rimuoverà il percorso anche se rimuovi il commento path.get = null;- di conseguenza quei percorsi saranno comunque inclusi nel file Swagger ma solo senza i dettagli. Potrebbe essere meglio includere il ApiExplorerSettingsAttributenella tua risposta come hai menzionato nella tua risposta originale su GitHub. L'uso di ApiExplorerSettings potrebbe anche evitare che le informazioni sul tipo vengano aggiunte schemesall'elenco del file Swagger .
JBert,

7

Preferirei rimuovere completamente le voci del dizionario per gli elementi del percorso:

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

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

Con questo approccio, non si otterrebbero elementi "vuoti" nella definizione swagger.json generata.


3

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

Crea un attributo

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

Applicare in startup.cs

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

Aggiungi l'attributo [SwaggerTag] ai metodi e ai controller che desideri includere in Swagger JSON


Dolce. Approccio appropriato e grazie per aver condiviso lo sln.
Vedran Mandić il

2

Può aiutare qualcuno ma durante lo sviluppo (debug) ci piace esporre interi controller e / o azioni e quindi nasconderli durante la produzione (build del rilascio)

#if DEBUG
    [ApiExplorerSettings(IgnoreApi = false)]
#else
    [ApiExplorerSettings(IgnoreApi = true)]
#endif  

1

Basato sulla risposta di @spottedmahns . Il mio compito era viceversa. Mostra solo quelli consentiti.

Strutture: .NetCore 2.1; Swagger: 3.0.0

Attributo aggiunto

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

E implementare IDocumentFilter personalizzato

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

Codice ConfigureServices :

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

    services.AddSwaggerGen(c =>
    {
        // other configurations
        c.DocumentFilter<ShowInSwaggerFilter>();
    });
}

Grazie Aleha. Questo approccio in realtà funziona bene per SwashBuckle.OData dove ApiExplorerSettingsAttribute non funziona.
Prasad Korhale,

1

aggiungi una riga 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

Aggiungi questo in cima ai tuoi metodi che vuoi omettere-

[ApiExplorerSettings(IgnoreApi=true)]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.