我目前在我的项目中使用招摇,我在那里有超过100个控制器。我想由于控制器数量众多,swagger UI文档页面需要超过5分钟才能加载其控制器。是否可以在UI页面中选择特定控制器并仅为它们加载选项? 或者还有其他方法可以更快地加载UI页面? 救救我!
答案 0 :(得分:8)
您可以在任一控制器上使用ApiExplorerSettings来完全忽略控制器或方法。
[ApiExplorerSettings(IgnoreApi = true)]
public class MyController
{
[ApiExplorerSettings(IgnoreApi = true)]
public string MyMethod
{
...
}
}
答案 1 :(得分:7)
使用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>();
请注意,虽然控制器已从规范中删除,但其他项目(如结果模型)仍将包含在规范中,并且可能仍会降低页面加载速度。
由于首先枚举所有控制器/模型等,它也可能很慢,在这种情况下,这可能没有帮助。
编辑:我注意到每次查看UI页面时都会重新生成整个定义(在您的方案中可能会出现问题)。幸运的是,缓存它非常容易(这应该很好,因为它不应该在运行时为大多数人改变)。
将此添加到您的配置中:
c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));
无耻地复制
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));
}
}
}
答案 2 :(得分:1)
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);
}
}
}
}
答案 3 :(得分:1)
作为对先前答案的回应,这是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");
}
}
答案 4 :(得分:1)
您可以尝试一下。您可以使用APIExplorerSetting来指定要包含在特定组中的API。
首先在Startup.cs中定义多个Swagger文档:
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