Показывать только выбранные контроллеры в пользовательском интерфейсе swagger-swashbuckle

В настоящее время я использую чванство в своем проекте, и у меня там более 100 контроллеров. Я предполагаю, что из-за большого количества контроллеров страница документации пользовательского интерфейса Swagger загружается более чем за 5 минут. Можно ли выбрать конкретные контроллеры на странице пользовательского интерфейса и загрузить параметры только для них? Или есть другие методы для более быстрой загрузки страницы пользовательского интерфейса? Помоги мне!


person Subash Kharel    schedule 20.01.2017    source источник
comment
Может, проблема в количестве контроллеров? Объединяйте или разделяйте приложения на отдельные домены. Сотня контроллеров в одном приложении представляет собой легкий запах.   -  person benPearce    schedule 13.02.2017


Ответы (5)


вы можете использовать ApiExplorerSettings на любом контроллере, чтобы полностью игнорировать контроллер или метод.

[ApiExplorerSettings(IgnoreApi = true)]
public class MyController
{
    [ApiExplorerSettings(IgnoreApi = true)]
    public string MyMethod
    {
      ...
    }
}
person peeyush rahariya    schedule 13.02.2017
comment
Мне нужно выбрать контроллер динамически. Я хочу иметь опцию в пользовательском интерфейсе swagger и выбирать контроллеры в опции и загружать их динамически. Является ли это возможным? - person Subash Kharel; 02.03.2017
comment
Это должен быть главный ответ! - person ianrathbone; 02.05.2019
comment
Что, если я хочу, чтобы это было включено / отключено в настройках приложений (Параметры ‹MyApplicationSettings›)? - person CodeHacker; 26.05.2021

Используя фильтр документов swashbuckle, вы можете удалить некоторые элементы сгенерированной спецификации постфактум, и тогда они не будут включены в интегрированный swagger-ui. Создайте класс, как показано ниже:

using System;
using System.Web.Http.Description;
using Swashbuckle.Swagger;

internal class SwaggerFilterOutControllers : IDocumentFilter
{
    void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (ApiDescription apiDescription in apiExplorer.ApiDescriptions)
        {
            Console.WriteLine(apiDescription.Route.RouteTemplate);

            if ((apiDescription.RelativePathSansQueryString().StartsWith("api/System/"))
                || (apiDescription.RelativePath.StartsWith("api/Internal/"))
                || (apiDescription.Route.RouteTemplate.StartsWith("api/OtherStuff/"))
                )
            {
                swaggerDoc.paths.Remove("/" + apiDescription.Route.RouteTemplate.TrimEnd('/'));
            }
        }
    }
}

а затем отредактируйте файл SwaggerConfig.cs, чтобы включить фильтр:

        GlobalConfiguration.Configuration
            .EnableSwagger(c =>
                    c.DocumentFilter<SwaggerFilterOutControllers>();

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

Это также может быть медленным просто из-за перечисления всех контроллеров / моделей и т. Д. В первую очередь, и в этом случае это может не помочь.

Изменить: я заметил, что при каждом просмотре страницы пользовательского интерфейса все определение будет восстанавливаться (что может быть вредным в вашем сценарии). К счастью, это очень легко кэшировать (что должно быть нормально, поскольку для большинства людей он не должен меняться во время выполнения).

Добавьте это в свою конфигурацию:

c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));

и используйте этот класс, бесстыдно скопированный с https://github.com/domaindrivendev/Swashbuckle/blob/master/Swashbuckle.Dummy.Core/App_Start/CachingSwaggerProvider.cs

using Swashbuckle.Swagger;
using System.Collections.Concurrent;

namespace <your namespace>
{
    public class CachingSwaggerProvider : ISwaggerProvider
    {
        private static ConcurrentDictionary<string, SwaggerDocument> _cache =
            new ConcurrentDictionary<string, SwaggerDocument>();

        private readonly ISwaggerProvider _swaggerProvider;

        public CachingSwaggerProvider(ISwaggerProvider swaggerProvider)
        {
            _swaggerProvider = swaggerProvider;
        }

        public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
        {
            string cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
            return _cache.GetOrAdd(cacheKey, (key) => _swaggerProvider.GetSwagger(rootUrl, apiVersion));
        }
    }
}
person Rory    schedule 28.03.2017
comment
Спасибо @rory_za. Теперь это работает для меня. Большое спасибо. - person Subash Kharel; 29.03.2017
comment
Удовольствие @SUBASH. Я рад, что теперь это работает на вас. Если этот или какой-либо ответ помог решить ваш вопрос, пожалуйста, примите его, нажав на галочку. Это показывает широкому сообществу, что вы нашли решение, и дает некоторую репутацию как автору, так и вам. Это не обязательно. - person Rory; 29.03.2017
comment
swaggerDoc.paths.Remove (/ + apiDescription.Route.RouteTemplate.TrimEnd ('/')); ничего не удалял. - person madufit1; 20.09.2018

В ответ на предыдущий ответ это обновленный код для ASP.NET Core. Я также добавил функцию удаления моделей.

using System;
using System.Linq;
using System.Web.Http;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.Swagger;

using Microsoft.AspNetCore.Mvc.ApiExplorer;

internal class SwaggerFilterOutControllers : IDocumentFilter
{

    void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach (var item in swaggerDoc.Paths.ToList())
        {
            if (!(item.Key.ToLower().Contains("/api/endpoint1") ||
                  item.Key.ToLower().Contains("/api/endpoint2")))
            {
                swaggerDoc.Paths.Remove(item.Key);
            }
        }

        swaggerDoc.Definitions.Remove("Model1");
        swaggerDoc.Definitions.Remove("Model2");
    }
}
person Andrew Samole    schedule 08.05.2019
comment
Куда мне поместить этот код? тот же каталог с startup.cs? - person linjunhalida; 27.02.2020
comment
Конечно, это не имеет значения. Просто убедитесь, что вы добавили это в свой Startup.cs services.AddSwaggerGen (options = ›options.DocumentFilter ‹SwaggerFilterOutControllers› (); - person Andrew Samole; 27.02.2020
comment
Взгляните на этот учебник, если заблудитесь: docs.microsoft.com/en-us/aspnet/core/tutorials/ - person Andrew Samole; 27.02.2020
comment
Версия, которую я использую, 5.6.1, использует OpenApiDocument вместо SwaggerDocument. Вероятно, есть и другие версии, которые делают то же самое. - person computercarguy; 28.09.2020

swaggerDoc.paths.Remove("/" + apiDescription.Route.RouteTemplate.TrimEnd('/')); мне ничего не удалил. Так,

internal class SwaggerFilterOutControllers : IDocumentFilter
{
    void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (var item in swaggerDoc.Paths.ToList())
        {
            if (!(item.Key.ToLower().Contains("/api/v1/xxxx") ||
                  item.Key.ToLower().Contains("/api/v1/yyyy")))
            {
                swaggerDoc.Paths.Remove(item.Key);
            }
        }
    }
}
person madufit1    schedule 20.09.2018

Вы можете попробовать это. Вы APIExplorerSetting, чтобы указать API, которые будут включены в определенную группу.

Начните с определения нескольких документов Swagger в Startup.cs:

services.AddSwaggerGen(c => { 
    c.SwaggerDoc("v1", new OpenApiInfo { 
        Title = "My API - V1",
        Version = "v1" 
    });
    c.SwaggerDoc("v2", new OpenApiInfo {
        Title = "My API - V2",
        Version = "v2"
    });
});

Затем украсьте отдельный контроллер указанными выше группами:

[ApiExplorerSettings(GroupName = "v2")]

Ссылка: https://github.com/domaindrivendev/Swashbuckle.AspNetCore#generate-multiple-swagger-documents

person Juber Pinjari    schedule 21.08.2020
comment
Включите образец кода из предлагаемого решения. Затем добавьте ссылку на документацию. Недостаточно только разместить ссылку на какой-либо документ, поскольку в будущем ссылка может устареть. - person Anouar; 21.08.2020
comment
Начните с определения нескольких документов Swagger в Startup.cs: services.AddSwaggerGen (c = ›{c.SwaggerDoc (v1, new OpenApiInfo {Title = My API - V1, Version = v1}); c.SwaggerDoc (v2, new OpenApiInfo { Title = My API - V2, Version = v2});}) Затем просто украсьте отдельный контроллер указанными выше группами: [ApiExplorerSettings (GroupName = v2)] - person Juber Pinjari; 22.08.2020
comment
Вам нужно отредактировать свой ответ, а не добавлять комментарий. - person Anouar; 24.08.2020