So lassen Sie Methoden aus der Swagger-Dokumentation zu WebAPI mit Swashbuckle weg

134

Ich habe eine C # ASP.NET-WebAPI-Anwendung mit API-Dokumentation, die automatisch mit Swashbuckle generiert wird . Ich möchte in der Lage sein, bestimmte Methoden in der Dokumentation wegzulassen, aber ich kann anscheinend nicht herausfinden, wie ich Swagger anweisen kann, sie nicht in die Swagger-UI-Ausgabe aufzunehmen.

Ich habe das Gefühl, dass dies mit dem Hinzufügen eines Modell- oder Schemafilters zu tun hat , aber es ist nicht klar, was zu tun ist, und die Dokumentation scheint nur Beispiele dafür zu enthalten, wie die Ausgabe für eine Methode geändert und nicht vollständig aus der Ausgabe entfernt werden kann.

Danke im Voraus.

Steve Wilkinson
quelle

Antworten:

336

Sie können Controllern und Aktionen das folgende Attribut hinzufügen, um sie von der generierten Dokumentation auszuschließen: [ApiExplorerSettings(IgnoreApi = true)]

mikesigs
quelle
12
Hat super funktioniert
4
Gibt es eine Möglichkeit, dies programmgesteuert zu tun? Ich möchte eine API in einigen Umgebungen verfügbar machen, in anderen jedoch nicht, gemäß einer Konfigurationseinstellung.
Paul Kienitz
@SyaifulNizamYahya Nicht sicher. Vielleicht [JsonIgnore]?
Mikeigsigs
@mikesigs Ja [JsonIgnore] funktioniert. Leider verbietet es die Serialisierung.
Syaiful Nizam Yahya
4
Swashbuckle Dokumentation: Arbitrary Operations
weglassen
17

Jemand hat die Lösung auf Github gepostet, also werde ich sie hier einfügen. Alle Credits gehen an ihn. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

Erstellen Sie zuerst eine Attributklasse

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

Erstellen Sie dann eine Dokumentfilterklasse

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

Fügen Sie dann in der Swagger Config-Klasse diesen Dokumentfilter hinzu

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

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

Der letzte Schritt besteht darin, dem Controller oder der Methode, für die Swashbuckle keine Dokumentation generieren soll, das Attribut [HideInDocsAttribute] hinzuzufügen.

Paulo Pozeti
quelle
1
Ich denke, RemoveRoute könnte der Droide sein, den ich suche.
Paul Kienitz
13

Sie können "Operationen" aus dem Swagger-Dokument entfernen, nachdem es mit einem Dokumentfilter generiert wurde. Setzen Sie das Verb einfach auf null(es gibt jedoch auch andere Möglichkeiten, dies zu tun).

Das folgende Beispiel erlaubt nur GETVerben - und stammt aus dieser Ausgabe .

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

und in deiner Prahlerkonfiguration:

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

    conf.DocumentFilter<RemoveVerbsFilter>();
});
Dave Transom
quelle
1
Beachten Sie: path.get = null;Dadurch wird der Pfad auch dann nicht entfernt, wenn Sie einen Kommentar abgeben. Infolgedessen werden diese Pfade weiterhin in die Swagger-Datei aufgenommen, jedoch nur ohne die Details. Es ist möglicherweise besser, das ApiExplorerSettingsAttributein Ihre Antwort aufzunehmen, wie Sie es in Ihrer ursprünglichen Antwort auf GitHub erwähnt haben. Durch die Verwendung von ApiExplorerSettings wird möglicherweise auch vermieden, dass Typinformationen zur schemesListe der Swagger-Datei hinzugefügt werden .
JBert
7

Ich würde es vorziehen, die Wörterbucheinträge für Pfadelemente vollständig zu entfernen:

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

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

Mit diesem Ansatz würden Sie keine "leeren" Elemente in der generierten swagger.json-Definition erhalten.

Denis Biondic
quelle
3

Machen Sie einen 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);
            }
        }
    }
}

Machen Sie ein Attribut

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

Bewerben Sie sich in startup.cs

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

Fügen Sie den Attributen und Controllern, die Sie in Swagger JSON aufnehmen möchten, das Attribut [SwaggerTag] hinzu

Rowan Stringer
quelle
Süss. Angemessener Ansatz und vielen Dank für das Teilen der SLN.
Vedran Mandić
2

Kann jemandem helfen, aber während der Entwicklung (Debugging) möchten wir ganze Controller und / oder Aktionen verfügbar machen und diese dann während der Produktion ausblenden (Release Build).

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

Basierend auf @spottedmahns Antwort . Meine Aufgabe war umgekehrt. Nur die erlaubten anzeigen.

Frameworks: .NetCore 2.1; Prahlerei: 3.0.0

Attribut hinzugefügt

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

Und implementieren Sie einen benutzerdefinierten 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>();
    });
}
aleha
quelle
Danke Aleha. Dieser Ansatz funktioniert tatsächlich gut für SwashBuckle.OData, wo ApiExplorerSettingsAttribute nicht funktioniert.
Prasad Korhale
1

füge eine Zeile hinzu 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
quelle
0

Fügen Sie dies zusätzlich zu Ihren Methoden hinzu, die Sie weglassen möchten.

[ApiExplorerSettings(IgnoreApi=true)]
Mridusmita Deka
quelle