c#版本是framework4.6.2,老版本的swagger没有分组优化
接口多了,放一起加载慢,优化后打开很流畅,按控制器打开

优化的代码
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")] namespace ShiNiu.PlatformApi { public class SwaggerConfig { public static void Register() { var thisAssembly = typeof(SwaggerConfig).Assembly; // 先获取所有控制器名称 var controllerNames = GetControllerNames(); var swaggerDocs = GlobalConfiguration.Configuration .EnableSwagger(c => { // ========== 使用 MultipleApiVersions 按控制器分组 ========== c.MultipleApiVersions( (apiDesc, targetApiVersion) => { var controllerName = apiDesc.ActionDescriptor.ControllerDescriptor.ControllerName; return targetApiVersion == controllerName; }, (vc) => { // 为每个控制器注册一个版本/分组 foreach (var name in controllerNames) { vc.Version(name, $"{name} 模块接口"); } } ); // ========== 配置文案 ========== c.IncludeXmlComments(string.Format("{0}/bin/xxx.XML", System.AppDomain.CurrentDomain.BaseDirectory)); c.IncludeXmlComments(string.Format("{0}/bin/xxx.XML", System.AppDomain.CurrentDomain.BaseDirectory)); c.IncludeXmlComments(string.Format("{0}/bin/xxx.XML", System.AppDomain.CurrentDomain.BaseDirectory)); c.DocumentFilter<HiddenApiFilter>(); c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider)); c.SchemaId(t => { if (t == null) return System.Guid.NewGuid().ToString("N"); string baseName = t.FullName ?? (t.Namespace != null ? t.Namespace + "." + t.Name : t.Name); if (t.IsGenericType) { try { var genericDef = t.GetGenericTypeDefinition(); var genericArgs = string.Join("_", t.GetGenericArguments() .Select(a => (a.FullName ?? a.Name).Replace('.', '_'))); var defName = genericDef.FullName ?? (genericDef.Namespace != null ? genericDef.Namespace + "." + genericDef.Name : genericDef.Name); baseName = defName + "_" + genericArgs; } catch { baseName = t.Name; } } return (baseName ?? t.Name).Replace('+', '_').Replace('.', '_'); }); c.OperationFilter<HttpHeaderFilter>(); c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); }); // ========== SwaggerUI 配置 ========== if (IsSwaggerUiEnabled()) { swaggerDocs.EnableSwaggerUi(c => { // 通过 DiscoveryPaths 注册所有分组 // 注意:需要把 discoveryPaths 设置为包含所有控制器名称 // 但由于 SwaggerUiConfig 构造时 discoveryPaths 已经传入了, // 这里通过反射或重新配置的方式处理 // 方法:使用 InjectJavaScript 自定义发现路径 // 或者直接修改模板参数 // 注入自定义 JavaScript 来支持多分组选择 c.InjectJavaScript(thisAssembly, "ShiNiu.PlatformApi.Scripts.swaggerui.swagger_lang.js"); }); } } private static List<string> GetControllerNames() { return AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.IsDynamic && !a.GlobalAssemblyCache) // 过滤系统程序集 .SelectMany(a => { try { return a.GetTypes(); } catch { return Type.EmptyTypes; } }) .Where(t => typeof(ApiController).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract) .Select(t => t.Name.EndsWith("Controller") ? t.Name.Replace("Controller", "") : t.Name) .Distinct() .ToList(); } private static bool IsSwaggerUiEnabled() { #if DEBUG return true; #else return false; #endif } } 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) { var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion); SwaggerDocument srcDoc = null; //只读取一次 if (!_cache.TryGetValue(cacheKey, out srcDoc)) { srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion); //srcDoc.info.description = "jiekoumiaoshu"; srcDoc.vendorExtensions = new Dictionary<string, object> { { "ControllerDesc", GetControllerDesc() } }; _cache.TryAdd(cacheKey, srcDoc); } return srcDoc; } /// <summary> /// 从API文档中读取控制器描述 /// </summary> /// <returns>所有控制器描述</returns> public static ConcurrentDictionary<string, string> GetControllerDesc() { string xmlpath = string.Format("{0}/bin/ShiNiu.PlatformApi.XML", System.AppDomain.CurrentDomain.BaseDirectory); ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>(); if (File.Exists(xmlpath)) { XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(xmlpath); string type = string.Empty, path = string.Empty, controllerName = string.Empty; string[] arrPath; int length = -1, cCount = "Controller".Length; XmlNode summaryNode = null; foreach (XmlNode node in xmldoc.SelectNodes("//member")) { type = node.Attributes["name"].Value; if (type.StartsWith("T:")) { //控制器 arrPath = type.Split('.'); length = arrPath.Length; controllerName = arrPath[length - 1]; if (controllerName.EndsWith("Controller")) { //获取控制器注释 summaryNode = node.SelectSingleNode("summary"); string key = controllerName.Remove(controllerName.Length - cCount, cCount); if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key)) { controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim()); } } } } } return controllerDescDict; } } }

浙公网安备 33010602011771号