C# 在大摇大摆的UI中仅显示选定的控制器

C# 在大摇大摆的UI中仅显示选定的控制器,c#,swagger,swagger-ui,swashbuckle,C#,Swagger,Swagger Ui,Swashbuckle,我目前在我的项目中使用swagger,我有100多个控制器。我猜由于控制器数量众多,swagger UI文档页面加载控制器需要5分钟以上。是否可以在UI页面上选择特定的控制器并仅为其加载选项? 或者有其他方法可以更快地加载UI页面? 救救我 您可以在任一控制器上使用ApiExplorerSettings完全忽略控制器,也可以在方法上使用ApiExplorerSettings [ApiExplorerSettings(IgnoreApi = true)] public class MyContro

我目前在我的项目中使用swagger,我有100多个控制器。我猜由于控制器数量众多,swagger UI文档页面加载控制器需要5分钟以上。是否可以在UI页面上选择特定的控制器并仅为其加载选项? 或者有其他方法可以更快地加载UI页面?
救救我

您可以在任一控制器上使用ApiExplorerSettings完全忽略控制器,也可以在方法上使用ApiExplorerSettings

[ApiExplorerSettings(IgnoreApi = true)]
public class MyController
{
    [ApiExplorerSettings(IgnoreApi = true)]
    public string MyMethod
    {
      ...
    }
}

使用Swashback的文档过滤器,您可以在事后删除生成的规范中的某些元素,这样它们就不会包含在集成的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>();
并利用这个类无耻地抄袭

使用虚张声势的皮带扣。虚张声势;
使用System.Collections.Concurrent;
名称空间
{
公共类CachingSwaggerProvider:ISwaggerProvider
{
专用静态ConcurrentDictionary\u缓存=
新的ConcurrentDictionary();
私有只读ISwaggerProvider(u-swaggerProvider);
公共CachingSwaggerProvider(ISwaggerProvider-swaggerProvider)
{
_斯威格提供者=斯威格提供者;
}
public-swagger文档GetSwagger(string-rootUrl,string-apiVersion)
{
string cacheKey=string.Format(“{0}{1}”,rootUrl,apiVersion);
返回_cache.GetOrAdd(cacheKey,(key)=>_swaggerProvider.GetSwagger(rootUrl,apiVersion));
}
}
}

swaggerDoc.path.Remove(“/”+apiscription.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);
            }
        }
    }
}

作为对前面答案的回应,这是ASP.NET核心的更新代码。我还添加了删除模型的功能

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

你可以试试这个。您可以使用APIExplorerSetting指定要包含在特定组中的API


首先在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")]

参考资料:

也许控制器的数量是问题所在?合并或拆分以分离域应用程序。一个应用程序中的100个控制器确实有点异味。我需要动态选择控制器。我希望在swagger UI中有一个选项,并在该选项中选择控制器并动态加载它们。有可能吗?这应该是最重要的答案<代码>使用Microsoft.AspNetCore.Mvc如果我想从应用程序设置(选项)中启用/禁用此功能,该怎么办?谢谢@rory_za。它现在正在为我工作。非常感谢。很高兴@SUBASH。我很高兴它现在对你有用。如果这个或任何答案已经解决了你的问题,请考虑点击复选标记。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。没有义务这样做。swaggerDoc.path.Remove(“/”+apiscription.Route.RouteTemplate.TrimEnd(“/”);没有删除任何内容。我应该将此代码放在哪里?与startup.cs的目录相同?当然,这并不重要。只需确保将其添加到Startup.cs services.AddSwaggerGen(options=>options.DocumentFilter()中即可;如果您迷路了,请看一下本教程:我使用的5.6.1版本使用了
OpenApiDocument
而不是
SwaggerDocument
。可能还有其他版本也有类似的功能。请包含建议解决方案中的示例代码。然后添加文档链接。仅发布指向某个文档的链接是不够的这个链接将来可能会过时。首先在Startup.cs:services.AddSwaggerGen(c=>{c.SwaggerDoc(“v1”,new openapinfo{Title=“My API-v1”,Version=“v1”)中定义多个Swagger文档;c.SwaggerDoc(“v2”,new openapinfo{Title=“My API-v2”,Version=“v2”})然后,只需使用上述组来装饰单个控制器:[ApiExplorerSettings(GroupName=“v2”)]您需要编辑答案,而不是添加注释。
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")]