Jak pominąć metody z dokumentacji Swaggera w WebAPI przy użyciu Swashbuckle

146

Mam aplikację WebAPI C # ASP.NET z dokumentacją API generowaną automatycznie przy użyciu Swashbuckle . Chcę móc pominąć pewne metody w dokumentacji, ale nie mogę znaleźć sposobu, aby powiedzieć Swaggerowi, aby nie uwzględniał ich w danych wyjściowych interfejsu użytkownika programu Swagger.

Czuję, że ma to coś wspólnego z dodaniem modelu lub filtru schematu, ale nie jest oczywiste, co należy zrobić, a dokumentacja wydaje się zawierać tylko przykłady tego, jak zmodyfikować dane wyjściowe dla metody, a nie usunąć je całkowicie z wyniku.

Z góry dziękuję.

SteveWilkinson
źródło

Odpowiedzi:

370

Możesz dodać następujący atrybut do kontrolerów i akcji, aby wykluczyć je z wygenerowanej dokumentacji: [ApiExplorerSettings(IgnoreApi = true)]

mikesigs
źródło
13
Działało świetnie, to powinna być odpowiedź
JohnC
6
Czy istnieje sposób na zrobienie tego programowo? Chcę udostępnić API w niektórych środowiskach, ale nie w innych, zgodnie z ustawieniami konfiguracji.
Paul Kienitz,
@SyaifulNizamYahya Not sure. Może [JsonIgnore]?
mikesigs
@mikesigs Yes [JsonIgnore] działa. Niestety zabrania serializacji.
Syaiful Nizam Yahya
4
Dokumentacja
Swashbuckle: Omit
18

Ktoś opublikował rozwiązanie na githubie, więc wkleię je tutaj. Wszystkie kredyty trafiają do niego. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

Najpierw utwórz klasę Attribute

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

Następnie utwórz klasę filtru dokumentów

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

Następnie w klasie Swagger Config dodaj ten filtr dokumentu

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

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

Ostatnim krokiem jest dodanie atrybutu [HideInDocsAttribute] do kontrolera lub metody, której nie chcesz, aby Swashbuckle generował dokumentację.

Paulo Pozeti
źródło
2
Myślę, że RemoveRoute może być droidem, którego szukam.
Paul Kienitz,
13

Możesz usunąć "operacje" z dokumentu swagger po jego wygenerowaniu za pomocą filtru dokumentu - po prostu ustaw czasownik na null(chociaż mogą być również inne sposoby, aby to zrobić)

Poniższy przykład dopuszcza tylko GETczasowniki - i pochodzi z tego problemu .

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

aw twojej konfiguracji swagger:

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

    conf.DocumentFilter<RemoveVerbsFilter>();
});
Dave Transom
źródło
1
Uwaga: to nie usunie ścieżki, nawet jeśli odkomentujesz path.get = null;- w rezultacie te ścieżki będą nadal zawarte w pliku Swagger, ale tylko bez szczegółów. Lepiej byłoby zawrzeć ApiExplorerSettingsAttributew swojej odpowiedzi słowo, o którym wspomniałeś w swojej oryginalnej odpowiedzi na GitHub. Użycie ApiExplorerSettings może również zapobiec dodawaniu informacji o typie do listy pliku Swagger schemes.
JBert
7

Wolałbym całkowicie usunąć wpisy słownika dla elementów ścieżki:

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

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

Przy takim podejściu w wygenerowanej definicji swagger.json nie uzyskasz „pustych” elementów.

Denis Biondic
źródło
4

Może komuś pomóc, ale podczas programowania (debugowania) lubimy ujawniać całe kontrolery i / lub akcje, a następnie ukrywać je podczas produkcji (kompilacja wydania)

#if DEBUG
    [ApiExplorerSettings(IgnoreApi = false)]
#else
    [ApiExplorerSettings(IgnoreApi = true)]
#endif  
Soeren Pedersen
źródło
3

Zrób filtr

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

Utwórz atrybut

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

Zastosuj w startup.cs

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

Dodaj atrybut [SwaggerTag] do metod i kontrolerów, które chcesz uwzględnić w Swagger JSON

Rowan Stringer
źródło
Słodkie. Odpowiednie podejście i dziękuję za udostępnienie sln.
Vedran Mandić
3

Dodaj to do swoich metod, które chcesz pominąć -

[ApiExplorerSettings(IgnoreApi=true)]
Mridusmita Deka
źródło
1

Na podstawie odpowiedzi @spottedmahns . Moje zadanie było odwrotnie. Pokaż tylko te, które są dozwolone.

Struktury: .NetCore 2.1; Swagger: 3.0.0

Dodatkowy atrybut

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

I zaimplementuj niestandardowy 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);
            }
        }
    }
}

Kod ConfigureServices :

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

    services.AddSwaggerGen(c =>
    {
        // other configurations
        c.DocumentFilter<ShowInSwaggerFilter>();
    });
}
aleha
źródło
Dzięki Aleha. To podejście faktycznie działa dobrze w przypadku SwashBuckle.OData, gdzie ApiExplorerSettingsAttribute nie działa.
Prasad Korhale
1

dodaj jedną linię 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
źródło
-2

Jeśli chcesz zapobiec wyświetlaniu w NestJS użycia

 @ApiExcludeEndpoint(true)
Shobhit Sharma
źródło
Brak wzmianki o nestjs w pytaniu
janv8000