diff --git a/Tiobon.Core.Extensions/Middlewares/SwaggerMiddleware.cs b/Tiobon.Core.Extensions/Middlewares/SwaggerMiddleware.cs
deleted file mode 100644
index 049549ea..00000000
--- a/Tiobon.Core.Extensions/Middlewares/SwaggerMiddleware.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using Tiobon.Core.Common;
-using Microsoft.AspNetCore.Builder;
-using Swashbuckle.AspNetCore.SwaggerUI;
-using System;
-using System.IO;
-using System.Linq;
-using Serilog;
-using static Tiobon.Core.Extensions.CustomApiVersion;
-
-namespace Tiobon.Core.Extensions.Middlewares
-{
- ///
- /// Swagger中间件
- ///
- public static class SwaggerMiddleware
- {
- public static void UseSwaggerMiddle(this IApplicationBuilder app, Func streamHtml)
- {
- if (app == null) throw new ArgumentNullException(nameof(app));
-
- app.UseSwagger();
- app.UseSwaggerUI(c =>
- {
- //根据版本名称倒序 遍历展示
- var apiName = AppSettings.app(new string[] { "Startup", "ApiName" });
- typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version => { c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{apiName} {version}"); });
-
- c.SwaggerEndpoint($"https://petstore.swagger.io/v2/swagger.json", $"{apiName} pet");
-
- // 将swagger首页,设置成我们自定义的页面,记得这个字符串的写法:{项目名.index.html}
- if (streamHtml.Invoke() == null)
- {
- var msg = "index.html的属性,必须设置为嵌入的资源";
- Log.Error(msg);
- throw new Exception(msg);
- }
-
- c.IndexStream = streamHtml;
- c.DocExpansion(DocExpansion.None); //->修改界面打开时自动折叠
-
- if (Permissions.IsUseIds4)
- {
- c.OAuthClientId("Tiobonadminjs");
- }
-
- //增加令牌本地缓存 reload不会丢失
- c.ConfigObject.AdditionalItems.Add("persistAuthorization","true");
-
- // 路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉,如果你想换一个路径,直接写名字即可,比如直接写c.RoutePrefix = "doc";
- c.RoutePrefix = "";
- });
- }
- }
-}
\ No newline at end of file
diff --git a/Tiobon.Core.Extensions/ServiceExtensions/SwaggerSetup.cs b/Tiobon.Core.Extensions/ServiceExtensions/SwaggerSetup.cs
index a2234bce..a144426b 100644
--- a/Tiobon.Core.Extensions/ServiceExtensions/SwaggerSetup.cs
+++ b/Tiobon.Core.Extensions/ServiceExtensions/SwaggerSetup.cs
@@ -9,6 +9,9 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using static Tiobon.Core.Extensions.CustomApiVersion;
+using Microsoft.AspNetCore.Builder;
+using Swashbuckle.AspNetCore.SwaggerUI;
+using Microsoft.Extensions.Options;
namespace Tiobon.Core.Extensions
{
@@ -22,48 +25,35 @@ namespace Tiobon.Core.Extensions
if (services == null) throw new ArgumentNullException(nameof(services));
var basePath = AppContext.BaseDirectory;
- //var basePath2 = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
- var ApiName = AppSettings.app(new string[] { "Startup", "ApiName" });
services.AddSwaggerGen(c =>
{
- //遍历出全部的版本,做文档信息展示
- typeof(ApiVersions).GetEnumNames().ToList().ForEach(version =>
+ ApiInfos.ForEach(x =>
{
- c.SwaggerDoc(version, new OpenApiInfo
- {
- Version = version,
- Title = $"{ApiName} 接口文档——{RuntimeInformation.FrameworkDescription}",
- Description = $"{ApiName} HTTP API " + version,
- //Contact = new OpenApiContact { Name = ApiName, Email = "Tiobon.Core@xxx.com", Url = new Uri("https://neters.club") },
- //License = new OpenApiLicense { Name = ApiName + " 官方文档", Url = new Uri("http://apk.neters.club/.doc/") }
- });
+ c.SwaggerDoc(x.UrlPrefix, x.OpenApiInfo);
c.OrderActionsBy(o => o.RelativePath);
});
-
c.UseInlineDefinitionsForEnums();
+ // 开启加权小锁
+ c.OperationFilter();
+ c.OperationFilter();
+
+ // 在header中添加token,传递到后台
+ c.OperationFilter();
+
+ // API注释所需XML文件
try
{
- //这个就是刚刚配置的xml文件名
- var xmlPath = Path.Combine(basePath, "Tiobon.Core.xml");
- //默认的第二个参数是false,这个是controller的注释,记得修改
- c.IncludeXmlComments(xmlPath, true);
-
- //这个就是Model层的xml文件名
- var xmlModelPath = Path.Combine(basePath, "Tiobon.Core.Model.xml");
- c.IncludeXmlComments(xmlModelPath);
+
+ c.IncludeXmlComments(Path.Combine(basePath, "Tiobon.Core.xml"), true);
+ c.IncludeXmlComments(Path.Combine(basePath, "Tiobon.Core.Model.xml"), true);
}
catch (Exception ex)
{
Log.Error("Tiobon.Core.xml和Tiobon.Core.Model.xml 丢失,请检查并拷贝。\n" + ex.Message);
}
- // 开启加权小锁
- c.OperationFilter();
- c.OperationFilter();
-
- // 在header中添加token,传递到后台
- c.OperationFilter();
+ c.MapType(() => new OpenApiSchema { Type = "string", Format = "string" });
// ids4和jwt切换
@@ -90,18 +80,176 @@ namespace Tiobon.Core.Extensions
}
else
{
- // Jwt Bearer 认证,必须是 oauth2
- c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
+ c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
+ Name = "Authorization",
+ Type = SecuritySchemeType.ApiKey,
+ BearerFormat = "JWT",
+ In = ParameterLocation.Header,
+ Scheme = "Bearer",
Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
- Name = "Authorization", //jwt默认的参数名称
- In = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
- Type = SecuritySchemeType.ApiKey
+
});
}
+
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "Bearer"
+ }
+ },
+ new List()
+ }
+ });
+
});
services.AddSwaggerGenNewtonsoftSupport();
}
+
+ public static void UseSwaggerMiddle(this IApplicationBuilder app, Func streamHtml)
+ {
+ if (app == null) throw new ArgumentNullException(nameof(app));
+
+ SwaggerBuilderExtensions.UseSwagger(app);
+ app.UseSwaggerUI(options =>
+ {
+ // 遍历分组信息,生成Json
+ ApiInfos.ForEach(x =>
+ {
+ options.SwaggerEndpoint($"/swagger/{x.UrlPrefix}/swagger.json", x.Name);
+ });
+ // 模型的默认扩展深度,设置为 -1 完全隐藏模型
+ options.DefaultModelsExpandDepth(-1);
+ // API文档仅展开标记
+ options.DocExpansion(DocExpansion.List);
+ // API前缀设置为空
+ options.RoutePrefix = string.Empty;
+ // API页面Title
+ options.DocumentTitle = "接口文档";
+ if (streamHtml.Invoke() == null)
+ {
+ var msg = "index.html的属性,必须设置为嵌入的资源";
+ Log.Error(msg);
+ throw new Exception(msg);
+ }
+
+ options.IndexStream = streamHtml;
+ options.DocExpansion(DocExpansion.None); //->修改界面打开时自动折叠
+
+ if (Permissions.IsUseIds4)
+ {
+ options.OAuthClientId("Tiobonadminjs");
+ }
+
+ //增加令牌本地缓存 reload不会丢失
+ options.ConfigObject.AdditionalItems.Add("persistAuthorization", "true");
+
+ // 路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件,注意localhost:8001/swagger是访问不到的,去launchSettings.json把launchUrl去掉,如果你想换一个路径,直接写名字即可,比如直接写c.RoutePrefix = "doc";
+ options.RoutePrefix = "";
+ });
+ }
+
+
+ ///
+ /// 当前API版本
+ ///
+ private static readonly string version = $"V1.0";
+ ///
+ /// Swagger分组信息,将进行遍历使用
+ ///
+ private static readonly List ApiInfos = new List()
+ {
+ new SwaggerApiInfo
+ {
+ UrlPrefix = Grouping.GroupName_Auth,
+ Name = "认证授权",
+ OpenApiInfo = new OpenApiInfo
+ {
+ Version = version,
+ Title = "认证授权",
+ Description = "登录/注销",
+ }
+ },
+ new SwaggerApiInfo
+ {
+ UrlPrefix = Grouping.GroupName_System,
+ Name = "系统模块",
+ OpenApiInfo = new OpenApiInfo
+ {
+ Version = version,
+ Title = "系统模块",
+ Description = "用户/角色/权限...",
+ }
+ },
+ new SwaggerApiInfo
+ {
+ UrlPrefix = Grouping.GroupName_Other,
+ Name = "其他模块",
+ OpenApiInfo = new OpenApiInfo
+ {
+ Version = version,
+ Title = "其他模块",
+ Description = "其他...",
+ }
+ },
+ new SwaggerApiInfo
+ {
+ UrlPrefix = Grouping.GroupName_Ghra,
+ Name = "Ghra模块",
+ OpenApiInfo = new OpenApiInfo
+ {
+ Version = version,
+ Title = "Ghra模块",
+ Description = "Ghra...",
+ }
+ }
+ };
+ private class SwaggerApiInfo
+ {
+ ///
+ /// URL前缀
+ ///
+ public string UrlPrefix { get; set; }
+
+ ///
+ /// 名称
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// OpenApiInfo
+ ///
+ public OpenApiInfo OpenApiInfo { get; set; }
+ }
+
+ ///
+ /// swagger分组
+ ///
+ public static class Grouping
+ {
+ ///
+ /// 系统
+ ///
+ public const string GroupName_System = "system";
+ ///
+ /// 认证授权
+ ///
+ public const string GroupName_Auth = "auth";
+ ///
+ /// 其他
+ ///
+ public const string GroupName_Other = "other";
+
+ ///
+ /// Ghra
+ ///
+ public const string GroupName_Ghra = "Ghra";
+ }
}
///
@@ -114,6 +262,10 @@ namespace Tiobon.Core.Extensions
///
public enum ApiVersions
{
+ ///
+ /// Ghra 版本
+ ///
+ Ghra = 0,
///
/// V1 版本
///