Как исключить методы из документации Swagger в WebAPI с помощью Swashbuckle

135

У меня есть приложение C # ASP.NET WebAPI с документацией API, автоматически создаваемой с помощью Swashbuckle . Я хочу иметь возможность исключить определенные методы из документации, но я не могу понять, как сказать Swagger не включать их в вывод пользовательского интерфейса Swagger.

Я чувствую, что это как-то связано с добавлением фильтра модели или схемы, но неясно, что делать, и документация, кажется, предоставляет только примеры того, как изменить вывод для метода, а не полностью удалить его из вывода.

Заранее спасибо.

SteveWilkinson
источник

Ответы:

338

Вы можете добавить следующий атрибут в Контроллеры и Действия, чтобы исключить их из созданной документации: [ApiExplorerSettings(IgnoreApi = true)]

mikesigs
источник
12
Отлично поработали, вот и ответ
JohnC
4
Есть ли способ сделать это программно? Я хочу предоставить API в некоторых средах, но не в других, в соответствии с настройками конфигурации.
Пол Кениц
@SyaifulNizamYahya Не уверен. Может быть [JsonIgnore]?
mikesigs
@mikesigs Да [JsonIgnore] работает. К сожалению, он запрещает сериализацию.
Syaiful Nizam Yahya
4
Документация Swashbuckle: опускать произвольные операции
spottedmahn
17

Кто-то разместил решение на github, поэтому я собираюсь вставить его сюда. Все заслуги принадлежат ему. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

Сначала создайте класс атрибута

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

Затем создайте класс фильтра документов

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

Затем в классе Swagger Config добавьте этот фильтр документов

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

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

Последний шаг - добавить атрибут [HideInDocsAttribute] к контроллеру или методу, который вы не хотите, чтобы Swashbuckle создавал документацию.

Пауло Позети
источник
1
Я думаю, что RemoveRoute может быть тем дроидом, которого я ищу.
Пол Кениц
13

Вы можете удалить «операции» из документа swagger после того, как он сгенерирован с помощью фильтра документа - просто установите глагол на null(хотя могут быть и другие способы сделать это)

В следующем примере разрешены только GETглаголы - он взят из этого выпуска .

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

и в вашей конфигурации чванства:

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

    conf.DocumentFilter<RemoveVerbsFilter>();
});
Дэйв Трансом
источник
1
Обратите внимание: это не удалит путь, даже если вы раскомментируете path.get = null;- в результате эти пути все равно будут включены в файл Swagger, но только без деталей. Возможно, было бы лучше включить ApiExplorerSettingsAttributeв свой ответ, как вы упомянули в своем исходном ответе на GitHub. Использование ApiExplorerSettings также может предотвратить добавление информации о типе в schemesсписок файла Swagger .
JBert
7

Я бы предпочел полностью удалить словарные записи для элементов пути:

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

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

При таком подходе вы не получите «пустых» элементов в сгенерированном определении swagger.json.

Денис Биондик
источник
3

Сделайте фильтр

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

Сделайте атрибут

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

Применить в startup.cs

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

Добавьте атрибут [SwaggerTag] к методам и контроллерам, которые вы хотите включить в Swagger JSON.

Роуэн Стрингер
источник
Сладкий. Соответствующий подход и спасибо, что поделились файлом sln.
Ведран Мандич
2

Может помочь кому-то, но во время разработки (отладки) нам нравится раскрывать целые контроллеры и / или действия, а затем скрывать их во время производства (сборка выпуска)

#if DEBUG
    [ApiExplorerSettings(IgnoreApi = false)]
#else
    [ApiExplorerSettings(IgnoreApi = true)]
#endif  
Соерен Педерсен
источник
1

На основе ответа @spottedmahns . Моя задача была наоборот. Показывать только разрешенные.

Фреймворки: .NetCore 2.1; Размах: 3.0.0

Добавлен атрибут

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

И реализовать собственный 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 :

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

    services.AddSwaggerGen(c =>
    {
        // other configurations
        c.DocumentFilter<ShowInSwaggerFilter>();
    });
}
Aleha
источник
Спасибо, Алеха. Этот подход действительно хорошо работает для SwashBuckle.OData, где ApiExplorerSettingsAttribute не работает.
Прасад Корхале
1

добавить одну строку 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
источник
0

Добавьте это поверх ваших методов, которые вы хотите опустить -

[ApiExplorerSettings(IgnoreApi=true)]
Мридусмита Дека
источник