Comment omettre des méthodes de la documentation Swagger sur WebAPI à l'aide de Swashbuckle

135

J'ai une application WebAPI C # ASP.NET avec la documentation API générée automatiquement à l'aide de Swashbuckle . Je veux pouvoir omettre certaines méthodes de la documentation, mais je n'arrive pas à trouver comment dire à Swagger de ne pas les inclure dans la sortie de l'interface utilisateur de Swagger.

Je sens que c'est quelque chose à voir avec l' ajout d'un modèle ou d'un filtre de schéma, mais ce n'est pas évident de savoir quoi faire et la documentation ne semble fournir que des exemples sur la façon de modifier la sortie d'une méthode, pas de la supprimer complètement de la sortie.

Merci d'avance.

SteveWilkinson
la source

Réponses:

337

Vous pouvez ajouter l'attribut suivant aux contrôleurs et actions pour les exclure de la documentation générée: [ApiExplorerSettings(IgnoreApi = true)]

mikesigs
la source
12
A très bien fonctionné, cela devrait être la réponse
JohnC
4
Existe-t-il un moyen de le faire par programme? Je souhaite exposer une API dans certains environnements mais pas dans d'autres, selon un paramètre de configuration.
Paul Kienitz
@SyaifulNizamYahya Pas sûr. Peut-être [JsonIgnore]?
mikesigs
@mikesigs Oui [JsonIgnore] fonctionne. Malheureusement, il interdit la sérialisation.
Syaiful Nizam Yahya
4
Documentation Swashbuckle: Omettre les opérations arbitraires
spottedmahn
17

Quelqu'un a posté la solution sur github donc je vais la coller ici. Tous les crédits lui reviennent. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

Créez d'abord une classe d'attribut

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

Créez ensuite une classe de filtre de document

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

Ensuite, dans la classe Swagger Config, ajoutez ce filtre de document

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

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

La dernière étape consiste à ajouter l'attribut [HideInDocsAttribute] sur le contrôleur ou la méthode dont vous ne voulez pas que Swashbuckle génère de la documentation.

Paulo Pozeti
la source
1
Je pense que RemoveRoute est peut-être le droïde que je recherche.
Paul Kienitz
13

Vous pouvez supprimer les "opérations" du document swagger après sa génération avec un filtre de document - il suffit de définir le verbe sur null(cependant, il peut y avoir d'autres façons de le faire)

L'exemple suivant autorise uniquement les GETverbes - et est tiré de ce problème .

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

et dans votre configuration swagger:

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

    conf.DocumentFilter<RemoveVerbsFilter>();
});
Dave Transom
la source
1
Remarque: cela ne supprimera pas le chemin même si vous décommentez path.get = null;- en conséquence, ces chemins seront toujours inclus dans le fichier Swagger mais seulement sans les détails. Il serait peut-être préférable d'inclure le ApiExplorerSettingsAttributedans votre réponse comme vous l'avez mentionné dans votre réponse d'origine sur GitHub. L'utilisation d'ApiExplorerSettings peut également éviter d'ajouter des informations de type à la schemesliste du fichier Swagger .
JBert
7

Je préférerais supprimer complètement les entrées du dictionnaire pour les éléments de chemin:

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

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

Avec cette approche, vous n'obtiendrez pas d'éléments "vides" dans la définition swagger.json générée.

Denis Biondic
la source
3

Faire un filtre

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

Faire un attribut

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

Appliquer dans startup.cs

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

Ajoutez l'attribut [SwaggerTag] aux méthodes et aux contrôleurs que vous souhaitez inclure dans Swagger JSON

Rowan Stringer
la source
Doux. Approche appropriée et merci pour le partage du sln.
Vedran Mandić
2

Peut aider quelqu'un, mais pendant le développement (débogage), nous aimons exposer des contrôleurs et / ou actions entiers, puis les masquer pendant la production (version de version)

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

Basé sur la réponse de @spottedmahns . Ma tâche était vice versa. Afficher uniquement ceux qui sont autorisés.

Cadres: .NetCore 2.1; Swagger: 3.0.0

Attribut ajouté

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

Et implémentez IDocumentFilter personnalisé

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

Code de ConfigureServices :

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

    services.AddSwaggerGen(c =>
    {
        // other configurations
        c.DocumentFilter<ShowInSwaggerFilter>();
    });
}
Aleha
la source
Merci Aleha. Cette approche fonctionne bien pour SwashBuckle.OData où ApiExplorerSettingsAttribute ne fonctionne pas.
Prasad Korhale du
1

ajouter une ligne 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
la source
0

Ajoutez ceci en plus de vos méthodes que vous souhaitez omettre.

[ApiExplorerSettings(IgnoreApi=true)]
Mridusmita Deka
la source