diff --git a/Attributes/SimApiAuthAttribute.cs b/Attributes/SimApiAuthAttribute.cs
index 7a652ee..1dff006 100644
--- a/Attributes/SimApiAuthAttribute.cs
+++ b/Attributes/SimApiAuthAttribute.cs
@@ -5,61 +5,54 @@ using Microsoft.AspNetCore.Mvc.Filters;
using SimApi.Communications;
using SimApi.Exceptions;
-namespace SimApi.Attributes
+namespace SimApi.Attributes;
+
+///
+/// 检测登录中间件
+///
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
+public class SimApiAuthAttribute : ActionFilterAttribute
{
- ///
- /// 检测登录中间件
- ///
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
- public class SimApiAuthAttribute : ActionFilterAttribute
+ private string[] Types { get; }
+
+
+ //默认是user登录类型
+ public SimApiAuthAttribute()
{
- private string[] Types { get; }
+ Types = new[] { "user" };
+ }
+ //只检测一种用户类型的快捷方式
+ public SimApiAuthAttribute(string type)
+ {
+ Types = type.Split(",");
+ }
- //默认是user登录类型
- public SimApiAuthAttribute()
+ //设定特定类型的检测
+ public SimApiAuthAttribute(string[] types)
+ {
+ Types = types;
+ }
+
+ //只检测一种用户类型的快捷方式
+ public SimApiAuthAttribute(string type, string url)
+ {
+ Types = new[] { type };
+ new HttpPostAttribute(url);
+ }
+
+ public override void OnActionExecuting(ActionExecutingContext context)
+ {
+ var loginInfo = (SimApiLoginItem)context.HttpContext.Items["LoginInfo"];
+ //检测是否登录
+ if (loginInfo == null)
{
- Types = new[]
- {
- "user"
- };
+ throw new SimApiException(401);
}
-
- //只检测一种用户类型的快捷方式
- public SimApiAuthAttribute(string type)
+ //检测用户类型
+ if (!Types.Intersect(loginInfo.Type).Any())
{
- Types = type.Split(",");
- }
-
- //设定特定类型的检测
- public SimApiAuthAttribute(string[] types)
- {
- Types = types;
- }
-
- //只检测一种用户类型的快捷方式
- public SimApiAuthAttribute(string type, string url)
- {
- Types = new[]
- {
- type
- };
- new HttpPostAttribute(url);
- }
-
- public override void OnActionExecuting(ActionExecutingContext context)
- {
- var loginInfo = (SimApiLoginItem)context.HttpContext.Items["LoginInfo"];
- //检测是否登录
- if (loginInfo == null)
- {
- throw new SimApiException(401);
- }
- //检测用户类型
- if (!Types.Intersect(loginInfo.Type).Any())
- {
- throw new SimApiException(403);
- }
+ throw new SimApiException(403);
}
}
}
\ No newline at end of file
diff --git a/Attributes/SimApiDocAttribute.cs b/Attributes/SimApiDocAttribute.cs
index 534a0bb..84a1171 100644
--- a/Attributes/SimApiDocAttribute.cs
+++ b/Attributes/SimApiDocAttribute.cs
@@ -1,25 +1,24 @@
-using System;
+using System;
using Swashbuckle.AspNetCore.Annotations;
-namespace SimApi.Attributes
+namespace SimApi.Attributes;
+
+///
+/// 快捷自定义接口文档类
+///
+[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
+public class SimApiDocAttribute : SwaggerOperationAttribute
{
///
- /// 快捷自定义接口文档类
+ /// 定义接口说明
///
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
- public class SimApiDocAttribute : SwaggerOperationAttribute
+ /// 接口分组
+ /// 接口名称
+ public SimApiDocAttribute(string tag, string name)
{
- ///
- /// 定义接口说明
- ///
- /// 接口分组
- /// 接口名称
- public SimApiDocAttribute(string tag, string name)
- {
- Tags = new[] { tag };
- Summary = name;
- // Consumes = new[] {"application/json"};
- // Produces = new[] {"application/json"};
- }
+ Tags = new[] { tag };
+ Summary = name;
+ // Consumes = new[] {"application/json"};
+ // Produces = new[] {"application/json"};
}
}
\ No newline at end of file
diff --git a/Communications/SimApiBaseRequest.cs b/Communications/SimApiBaseRequest.cs
index ba55ccd..d84f76b 100644
--- a/Communications/SimApiBaseRequest.cs
+++ b/Communications/SimApiBaseRequest.cs
@@ -1,23 +1,22 @@
-namespace SimApi.Communications
-{
- ///
- /// 只有ID的请求
- ///
- public record SimApiIdOnlyRequest(int Id);
+namespace SimApi.Communications;
- ///
- /// 只有ID的请求(字符串)
- ///
- public record SimApiStringIdOnlyRequest(string Id);
+///
+/// 只有ID的请求
+///
+public record SimApiIdOnlyRequest(int Id);
- ///
- /// 动态类型单字段请求
- ///
- ///
- public record SimApiOneFieldRequest(T Data);
+///
+/// 只有ID的请求(字符串)
+///
+public record SimApiStringIdOnlyRequest(string Id);
- ///
- /// 基础分页请求
- ///
- public record SimApiBasePageRequest(int Page, int Count);
-}
\ No newline at end of file
+///
+/// 动态类型单字段请求
+///
+///
+public record SimApiOneFieldRequest(T Data);
+
+///
+/// 基础分页请求
+///
+public record SimApiBasePageRequest(int Page, int Count);
\ No newline at end of file
diff --git a/Communications/SimApiBaseResponse.cs b/Communications/SimApiBaseResponse.cs
index 00b70f1..5ff9d68 100644
--- a/Communications/SimApiBaseResponse.cs
+++ b/Communications/SimApiBaseResponse.cs
@@ -2,75 +2,64 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace SimApi.Communications
+namespace SimApi.Communications;
+
+///
+/// 基础相应
+///
+public record SimApiBaseResponse(int Code = 200, string Message = "成功")
{
///
- /// 基础相应
+ /// 默认错误代码对应提示信息
///
- public record SimApiBaseResponse(int Code = 200, string Message = "成功")
+ private static readonly Dictionary MsgBox = new()
{
- ///
- /// 默认错误代码对应提示信息
- ///
- private static readonly Dictionary MsgBox = new()
- {
- {
- 200, "成功"
- },
- {
- 204, "没有数据"
- },
- {
- 400, "参数错误"
- },
- {
- 401, "需要登录"
- },
- {
- 403, "无权访问"
- },
- {
- 404, "接口不存在"
- },
- {
- 500, "服务器错误"
- }
- };
+ { 200, "成功" },
+ { 204, "没有数据" },
+ { 400, "参数错误" },
+ { 401, "需要登录" },
+ { 403, "无权访问" },
+ { 404, "接口不存在" },
+ { 500, "服务器错误" }
+ };
- public SimApiBaseResponse(int code) : this(code, MsgBox.ContainsKey(code) ? MsgBox[code] : "未知错误")
- {
- }
-
- ///
- /// 序列化为JSON字符串
- ///
- ///
- public override string ToString()
- {
- return JsonSerializer.Serialize(this, new JsonSerializerOptions
- {
- IgnoreReadOnlyProperties = true,
- PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
- Converters =
- {
- new JsonStringEnumConverter()
- }
- });
- }
+ public SimApiBaseResponse(int code) : this(code, MsgBox.ContainsKey(code) ? MsgBox[code] : "未知错误")
+ {
}
///
- /// 动态内容分页
+ /// 序列化为JSON字符串
///
- ///
- public record SimApiBasePageResponse
- (T List, int Page = 1, int Count = 1, int Total = 1, int Code = 200,
- string Message = "成功") : SimApiBaseResponse(Code, Message);
+ ///
+ public override string ToString()
+ {
+ return JsonSerializer.Serialize(this, new JsonSerializerOptions
+ {
+ IgnoreReadOnlyProperties = true,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ Converters =
+ {
+ new JsonStringEnumConverter()
+ }
+ });
+ }
+}
- ///
- /// 动态Data返回
- ///
- ///
- public record SimApiBaseResponse(T Data, int Code = 200, string Message = "成功") : SimApiBaseResponse(Code,
- Message);
-}
\ No newline at end of file
+///
+/// 动态内容分页
+///
+///
+public record SimApiBasePageResponse(
+ T List,
+ int Page = 1,
+ int Count = 1,
+ int Total = 1,
+ int Code = 200,
+ string Message = "成功") : SimApiBaseResponse(Code, Message);
+
+///
+/// 动态Data返回
+///
+///
+public record SimApiBaseResponse(T Data, int Code = 200, string Message = "成功") : SimApiBaseResponse(Code,
+ Message);
\ No newline at end of file
diff --git a/Communications/SimApiLoginItem.cs b/Communications/SimApiLoginItem.cs
index 7552735..8c703ec 100644
--- a/Communications/SimApiLoginItem.cs
+++ b/Communications/SimApiLoginItem.cs
@@ -1,7 +1,6 @@
-namespace SimApi.Communications
-{
- ///
- /// 登录信息中间件
- ///
- public record SimApiLoginItem(string Id, string[] Type);
-}
\ No newline at end of file
+namespace SimApi.Communications;
+
+///
+/// 登录信息中间件
+///
+public record SimApiLoginItem(string Id, string[] Type);
\ No newline at end of file
diff --git a/Configurations/SimApiDocOptions.cs b/Configurations/SimApiDocOptions.cs
index 00a1e1e..2f833cc 100644
--- a/Configurations/SimApiDocOptions.cs
+++ b/Configurations/SimApiDocOptions.cs
@@ -1,73 +1,75 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using Swashbuckle.AspNetCore.SwaggerUI;
-namespace SimApi.Configs
+namespace SimApi.Configs;
+
+///
+/// 文档组配置
+///
+public class SimApiDocGroupOption
+{
+ ///
+ /// 文档标识
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// 文档名称
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// 文档描述
+ ///
+ public string Description { get; set; }
+}
+
+///
+/// 授权配置, Type支持 "SimApiAuth","ClientCredentials","Implicit","AuthorizationCode"
+///
+public class SimApiAuthOption
+{
+ public string[] Type { get; set; } = new[] { "SimApiAuth" };
+
+ public string Description { get; set; } = "认证服务器颁发的AccessToken";
+
+ public string AuthorizationUrl { get; set; }
+
+ public string TokenUrl { get; set; }
+
+ public Dictionary Scopes { get; set; }
+}
+
+///
+/// 文档配置
+///
+public class SimApiDocOptions
{
///
/// 文档组配置
///
- public class SimApiDocGroupOption
+ public SimApiDocGroupOption[] ApiGroups { get; set; } = new[]
{
- ///
- /// 文档标识
- ///
- public string Id { get; set; }
-
- ///
- /// 文档名称
- ///
- public string Name { get; set; }
-
- ///
- /// 文档描述
- ///
- public string Description { get; set; }
- }
-
- ///
- /// 授权配置, Type支持 "SimApiAuth","ClientCredentials","Implicit","AuthorizationCode"
- ///
- public class SimApiAuthOption
- {
- public string[] Type { get; set; } = new[] {"SimApiAuth"};
- public string Description { get; set; } = "认证服务器颁发的AccessToken";
- public string AuthorizationUrl { get; set; }
- public string TokenUrl { get; set; }
- public Dictionary Scopes { get; set; }
- }
-
- ///
- /// 文档配置
- ///
- public class SimApiDocOptions
- {
- ///
- /// 文档组配置
- ///
- public SimApiDocGroupOption[] ApiGroups { get; set; } = new[]
+ new SimApiDocGroupOption
{
- new SimApiDocGroupOption
- {
- Id = "api",
- Name = "Api",
- Description = "Api接口文档"
- }
- };
+ Id = "api",
+ Name = "Api",
+ Description = "Api接口文档"
+ }
+ };
- ///
- /// 授权配置
- ///
- public SimApiAuthOption ApiAuth { get; set; } = new SimApiAuthOption();
+ ///
+ /// 授权配置
+ ///
+ public SimApiAuthOption ApiAuth { get; set; } = new SimApiAuthOption();
- ///
- /// 文档页面标题
- ///
- public string DocumentTitle { get; set; } = "API接口文档";
-
- ///
- /// 接口支持的调用方式
- ///
- public SubmitMethod[] SupportedMethod { get; set; } = new[] {SubmitMethod.Post};
- }
+ ///
+ /// 文档页面标题
+ ///
+ public string DocumentTitle { get; set; } = "API接口文档";
+
+ ///
+ /// 接口支持的调用方式
+ ///
+ public SubmitMethod[] SupportedMethod { get; set; } = new[] { SubmitMethod.Post };
}
\ No newline at end of file
diff --git a/Configurations/SimApiOptions.cs b/Configurations/SimApiOptions.cs
index 678fc66..31e8e58 100644
--- a/Configurations/SimApiOptions.cs
+++ b/Configurations/SimApiOptions.cs
@@ -1,93 +1,92 @@
using System;
-namespace SimApi.Configs
+namespace SimApi.Configs;
+
+public class SimApiOptions
{
- public class SimApiOptions
+ ///
+ /// 启用全部Cors,对于开发前后分离的时候很有用。
+ /// default: true
+ ///
+ public bool EnableCors { get; set; } = true;
+
+ ///
+ /// 启用SimapiAuth,一个简单的基于Header Token的认证方式。
+ /// default: false
+ ///
+ public bool EnableSimApiAuth { get; set; } = false;
+
+ ///
+ /// 启用在线文档,启用后 访问 /swagger 可以查看对应的api文档。
+ /// default: false
+ ///
+ public bool EnableSimApiDoc { get; set; } = false;
+
+ ///
+ /// 启用异常拦截,启用后,所有的异常将被通过json反馈。
+ /// default: true
+ ///
+ public bool EnableSimApiException { get; set; } = true;
+
+ ///
+ /// 开启S3兼容的存储系统。
+ /// default: false
+ ///
+ public bool EnableSimApiStorage { get; set; } = false;
+
+ ///
+ /// 开启ForwardHeaders,开启后可以透传负载均衡的Headers
+ /// default: true
+ ///
+ public bool EnableForwardHeaders { get; set; } = true;
+
+ ///
+ /// 将所有的url都格式化为小写字母
+ /// default: true
+ ///
+ public bool EnableLowerUrl { get; set; } = true;
+
+ ///
+ /// 启用格式化的 Console Logger
+ /// default: false
+ ///
+ public bool EnableLogger { get; set; } = false;
+
+ ///
+ /// 是否启用Synapse
+ ///
+ public bool EnableSynapse { get; set; } = false;
+
+
+ ///
+ /// Swagger文档相关配置,需要启用 EnableSimApiDoc
+ ///
+ public SimApiDocOptions SimApiDocOptions { get; set; } = new();
+
+ ///
+ /// S3兼容的存储系统配置,需要启用 EnableSimApiStorage
+ ///
+ public SimApiStorageOptions SimApiStorageOptions { get; set; } = new();
+
+ public SimApiSynapseOptions SimApiSynapseOptions { get; set; } = new();
+
+ public void ConfigureSimApiSynapse(Action options = null)
{
- ///
- /// 启用全部Cors,对于开发前后分离的时候很有用。
- /// default: true
- ///
- public bool EnableCors { get; set; } = true;
+ options?.Invoke(SimApiSynapseOptions);
+ }
- ///
- /// 启用SimapiAuth,一个简单的基于Header Token的认证方式。
- /// default: false
- ///
- public bool EnableSimApiAuth { get; set; } = false;
+ public void ConfigureSimApiSynapse(SimApiSynapseOptions options)
+ {
+ SimApiSynapseOptions = options;
+ }
- ///
- /// 启用在线文档,启用后 访问 /swagger 可以查看对应的api文档。
- /// default: false
- ///
- public bool EnableSimApiDoc { get; set; } = false;
+ public void ConfigureSimApiDoc(Action options = null)
+ {
+ options?.Invoke(SimApiDocOptions);
+ }
- ///
- /// 启用异常拦截,启用后,所有的异常将被通过json反馈。
- /// default: true
- ///
- public bool EnableSimApiException { get; set; } = true;
-
- ///
- /// 开启S3兼容的存储系统。
- /// default: false
- ///
- public bool EnableSimApiStorage { get; set; } = false;
-
- ///
- /// 开启ForwardHeaders,开启后可以透传负载均衡的Headers
- /// default: true
- ///
- public bool EnableForwardHeaders { get; set; } = true;
-
- ///
- /// 将所有的url都格式化为小写字母
- /// default: true
- ///
- public bool EnableLowerUrl { get; set; } = true;
-
- ///
- /// 启用格式化的 Console Logger
- /// default: false
- ///
- public bool EnableLogger { get; set; } = false;
-
- ///
- /// 是否启用Synapse
- ///
- public bool EnableSynapse { get; set; } = false;
-
-
- ///
- /// Swagger文档相关配置,需要启用 EnableSimApiDoc
- ///
- public SimApiDocOptions SimApiDocOptions { get; set; } = new();
-
- ///
- /// S3兼容的存储系统配置,需要启用 EnableSimApiStorage
- ///
- public SimApiStorageOptions SimApiStorageOptions { get; set; } = new();
-
- public SimApiSynapseOptions SimApiSynapseOptions { get; set; } = new();
-
- public void ConfigureSimApiSynapse(Action options = null)
- {
- options?.Invoke(SimApiSynapseOptions);
- }
-
- public void ConfigureSimApiSynapse(SimApiSynapseOptions options)
- {
- SimApiSynapseOptions = options;
- }
-
- public void ConfigureSimApiDoc(Action options = null)
- {
- options?.Invoke(SimApiDocOptions);
- }
-
- public void ConfigureSimApiStorage(Action options = null)
- {
- options?.Invoke(SimApiStorageOptions);
- }
+ public void ConfigureSimApiStorage(Action options = null)
+ {
+ options?.Invoke(SimApiStorageOptions);
}
}
\ No newline at end of file
diff --git a/Configurations/SimApiStorageOptions.cs b/Configurations/SimApiStorageOptions.cs
index 92ade77..d3203cb 100644
--- a/Configurations/SimApiStorageOptions.cs
+++ b/Configurations/SimApiStorageOptions.cs
@@ -1,24 +1,23 @@
-namespace SimApi.Configs
+namespace SimApi.Configs;
+
+public class SimApiStorageOptions
{
- public class SimApiStorageOptions
- {
- ///
- /// S3 服务器入口地址
- ///
- public string Endpoint { get; set; }
+ ///
+ /// S3 服务器入口地址
+ ///
+ public string Endpoint { get; set; }
- ///
- /// S3 服务器文件访问地址
- ///
- public string ServeUrl { get; set; }
+ ///
+ /// S3 服务器文件访问地址
+ ///
+ public string ServeUrl { get; set; }
- ///
- /// S3服务 Bucket
- ///
- public string Bucket { get; set; }
+ ///
+ /// S3服务 Bucket
+ ///
+ public string Bucket { get; set; }
- public string AccessKey { get; set; }
+ public string AccessKey { get; set; }
- public string SecretKey { get; set; }
- }
+ public string SecretKey { get; set; }
}
\ No newline at end of file
diff --git a/Controllers/SimApiBaseController.cs b/Controllers/SimApiBaseController.cs
index b126469..80ea814 100644
--- a/Controllers/SimApiBaseController.cs
+++ b/Controllers/SimApiBaseController.cs
@@ -4,84 +4,82 @@ using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Linq;
using SimApi.Exceptions;
-using SimApi.Attributes;
-namespace SimApi.Controllers
+namespace SimApi.Controllers;
+
+///
+/// 基础控制器,所有控制器均继承本控制器
+/// 1. 自动验证请求参数
+/// 2. 报错返回
+/// 3. 错误回馈页面
+///
+public class SimApiBaseController : Controller
{
///
- /// 基础控制器,所有控制器均继承本控制器
- /// 1. 自动验证请求参数
- /// 2. 报错返回
- /// 3. 错误回馈页面
+ /// 当前登录用户的ID
///
- public class SimApiBaseController : Controller
+ protected SimApiLoginItem LoginInfo => (SimApiLoginItem)HttpContext.Items["LoginInfo"];
+
+ ///
+ /// 验证请求参数
+ ///
+ ///
+ public override void OnActionExecuting(ActionExecutingContext context)
{
- ///
- /// 当前登录用户的ID
- ///
- protected SimApiLoginItem LoginInfo => (SimApiLoginItem)HttpContext.Items["LoginInfo"];
-
- ///
- /// 验证请求参数
- ///
- ///
- public override void OnActionExecuting(ActionExecutingContext context)
+ if (!context.ModelState.IsValid)
{
- if (!context.ModelState.IsValid)
+ foreach (var item in context.ModelState.Values.Where(item =>
+ item.ValidationState == ModelValidationState.Invalid))
{
- foreach (var item in context.ModelState.Values.Where(item =>
- item.ValidationState == ModelValidationState.Invalid))
- {
- Error(400, item.Errors.First().ErrorMessage);
- break;
- }
+ Error(400, item.Errors.First().ErrorMessage);
+ break;
}
}
+ }
- ///
- /// 错误返回
- ///
- /// 错误代码
- /// 错误描述(若是常规错误,代码可自动带取描述)
- ///
- protected static void Error(int code = 500, string message = "")
- {
- throw new SimApiException(code, message);
- }
+ ///
+ /// 错误返回
+ ///
+ /// 错误代码
+ /// 错误描述(若是常规错误,代码可自动带取描述)
+ ///
+ protected static void Error(int code = 500, string message = "")
+ {
+ throw new SimApiException(code, message);
+ }
- ///
- /// 检测条件,根据条件返回报错
- ///
- /// 检测条件
- /// 错误代码
- /// 错误描述
- protected static void ErrorWhen(bool condition, int code = 500, string message = "")
+ ///
+ /// 检测条件,根据条件返回报错
+ ///
+ /// 检测条件
+ /// 错误代码
+ /// 错误描述
+ protected static void ErrorWhen(bool condition, int code = 500, string message = "")
+ {
+ if (condition)
{
- if (condition)
- {
- Error(code, message);
- }
+ Error(code, message);
}
+ }
- ///
- /// 检测给定的变量是否为NUll
- ///
- /// 检测条件
- /// 错误代码
- /// 错误描述
- protected static void ErrorWhenNull(object condition, int code = 404, string message = "")
- {
- ErrorWhen(condition == null, code, message);
- }
+ ///
+ /// 检测给定的变量是否为NUll
+ ///
+ /// 检测条件
+ /// 错误代码
+ /// 错误描述
+ protected static void ErrorWhenNull(object condition, int code = 404, string message = "")
+ {
+ ErrorWhen(condition == null, code, message);
+ }
- ///
- /// 上传文件
- ///
- ///
- protected SimApiBaseResponse UploadFile()
- {
- return new SimApiBaseResponse(null);
- }
+ ///
+ /// 上传文件
+ ///
+ ///
+ protected SimApiBaseResponse UploadFile()
+ {
+ return new SimApiBaseResponse(null);
}
}
\ No newline at end of file
diff --git a/Controllers/SimApiCommonController.cs b/Controllers/SimApiCommonController.cs
index 3e48f55..486beab 100644
--- a/Controllers/SimApiCommonController.cs
+++ b/Controllers/SimApiCommonController.cs
@@ -1,60 +1,51 @@
-using System;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using SimApi.Attributes;
using SimApi.Communications;
using SimApi.Helpers;
-namespace SimApi.Controllers
+namespace SimApi.Controllers;
+
+[ApiExplorerSettings(GroupName = "api")]
+public class SimApiCommonController(SimApiAuth auth) : SimApiBaseController
{
- [ApiExplorerSettings(GroupName = "api")]
- public class YYCommonController : SimApiBaseController
+ ///
+ /// 错误回馈页面
+ ///
+ /// 错误代码
+ ///
+ [HttpGet("exception/{code:int}")]
+ [ApiExplorerSettings(IgnoreApi = true)]
+ public SimApiBaseResponse ExceptionHandler(int code)
{
- private SimApiAuth Auth { get; }
+ return new SimApiBaseResponse(code);
+ }
- public YYCommonController(SimApiAuth auth)
+ ///
+ /// 检测用户登陆的控制器
+ ///
+ ///
+ [HttpPost("/auth/check"), SimApiDoc("认证", "检测登陆")]
+ public SimApiBaseResponse CheckLogin()
+ {
+ ErrorWhenNull(LoginInfo, 401);
+ return new SimApiBaseResponse(LoginInfo.Id);
+ }
+
+ ///
+ /// 退出登陆
+ ///
+ ///
+ [HttpPost("/auth/logout"), SimApiDoc("认证", "退出登陆")]
+ public SimApiBaseResponse Logout()
+ {
+ string token = null;
+
+ if (Request.Headers.ContainsKey("Token"))
{
- Auth = auth;
+ token = Request.Headers["Token"];
}
- ///
- /// 错误回馈页面
- ///
- /// 错误代码
- ///
- [HttpGet("exception/{code:int}")]
- [ApiExplorerSettings(IgnoreApi = true)]
- public SimApiBaseResponse ExceptionHandler(int code)
- {
- return new SimApiBaseResponse(code);
- }
-
- ///
- /// 检测用户登陆的控制器
- ///
- ///
- [HttpPost("/auth/check"), SimApiDoc("认证", "检测登陆")]
- public SimApiBaseResponse CheckLogin()
- {
- ErrorWhenNull(LoginInfo, 401);
- return new SimApiBaseResponse(LoginInfo.Id);
- }
-
- ///
- /// 退出登陆
- ///
- ///
- [HttpPost("/auth/logout"), SimApiDoc("认证", "退出登陆")]
- public SimApiBaseResponse Logout()
- {
- string token = null;
-
- if (Request.Headers.ContainsKey("Token"))
- {
- token = Request.Headers["Token"];
- }
-
- Auth.Logout(token);
- return new SimApiBaseResponse();
- }
+ auth.Logout(token);
+ return new SimApiBaseResponse();
}
}
\ No newline at end of file
diff --git a/Exceptions/SimApiException.cs b/Exceptions/SimApiException.cs
index b3cd116..cae9202 100644
--- a/Exceptions/SimApiException.cs
+++ b/Exceptions/SimApiException.cs
@@ -1,16 +1,11 @@
using System;
-namespace SimApi.Exceptions
-{
- ///
- /// Api错误捕获异常
- ///
- public class SimApiException : Exception
- {
- public int Code { get; }
- public SimApiException(int code, string message = "") : base(message)
- {
- Code = code;
- }
- }
-}
+namespace SimApi.Exceptions;
+
+///
+/// Api错误捕获异常
+///
+public class SimApiException(int code, string message = "") : Exception(message)
+{
+ public int Code { get; } = code;
+}
\ No newline at end of file
diff --git a/Helpers/SimApiAuth.cs b/Helpers/SimApiAuth.cs
index f5ec70d..f529518 100644
--- a/Helpers/SimApiAuth.cs
+++ b/Helpers/SimApiAuth.cs
@@ -1,60 +1,48 @@
using System;
using System.Text.Json;
-using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using SimApi.Communications;
-namespace SimApi.Helpers
+namespace SimApi.Helpers;
+
+///
+/// 认证助手
+///
+public class SimApiAuth(IDistributedCache cache)
{
///
- /// 认证助手
+ /// 产生一个Token记录并返回Token
///
- public class SimApiAuth
+ ///
+ ///
+ public string Login(string id, string type = "user", string token = null)
{
- private IDistributedCache Cache { get; }
+ return Login(id, new[] { type }, token);
+ }
- public SimApiAuth(IDistributedCache cache)
- {
- Cache = cache;
- }
+ ///
+ /// 产生一个Token并记录用户ID角色[多角色]
+ ///
+ ///
+ ///
+ ///
+ public string Login(string id, string[] type, string uuid = null)
+ {
+ uuid ??= Guid.NewGuid().ToString();
+ var loginItem = new SimApiLoginItem(id, type);
+ cache.SetString(uuid, JsonSerializer.Serialize(loginItem));
+ return uuid;
+ }
- ///
- /// 产生一个Token记录并返回Token
- ///
- ///
- ///
- public string Login(string id, string type = "user", string token = null)
+ ///
+ /// 退出登陆
+ ///
+ /// 登陆标识
+ public void Logout(string uuid)
+ {
+ if (!string.IsNullOrEmpty(uuid))
{
- return Login(id, new[]
- {
- type
- }, token);
- }
-
- ///
- /// 产生一个Token并记录用户ID角色[多角色]
- ///
- ///
- ///
- ///
- public string Login(string id, string[] type, string uuid = null)
- {
- uuid ??= Guid.NewGuid().ToString();
- var loginItem = new SimApiLoginItem(id, type);
- Cache.SetString(uuid, JsonSerializer.Serialize(loginItem));
- return uuid;
- }
-
- ///
- /// 退出登陆
- ///
- /// 登陆标识
- public void Logout(string uuid)
- {
- if (!string.IsNullOrEmpty(uuid))
- {
- Cache.Remove(uuid);
- }
+ cache.Remove(uuid);
}
}
}
\ No newline at end of file
diff --git a/Helpers/SimApiStorage.cs b/Helpers/SimApiStorage.cs
index 11a73b0..53884d7 100644
--- a/Helpers/SimApiStorage.cs
+++ b/Helpers/SimApiStorage.cs
@@ -2,102 +2,100 @@
using System.IO;
using Microsoft.AspNetCore.Http;
using Minio;
-using Minio.Exceptions;
using SimApi.Configs;
-namespace SimApi.Helpers
+namespace SimApi.Helpers;
+
+public class SimApiStorage
{
- public class SimApiStorage
+ private MinioClient Mc { get; }
+
+ public MinioClient Client => Mc;
+
+ private string ServeUrl { get; }
+
+ public string Bucket { get; }
+
+ private IHttpContextAccessor HttpContextAccessor { get; }
+
+ public SimApiStorage(SimApiOptions apiOptions, IHttpContextAccessor httpContextAccessor)
{
- private MinioClient Mc { get; }
-
- public MinioClient Client => Mc;
-
- private string ServeUrl { get; }
-
- public string Bucket { get; }
-
- private IHttpContextAccessor HttpContextAccessor { get; }
-
- public SimApiStorage(SimApiOptions apiOptions, IHttpContextAccessor httpContextAccessor)
+ var options = apiOptions.SimApiStorageOptions;
+ HttpContextAccessor = httpContextAccessor;
+ var useSsl = false;
+ string endpoint;
+ if (options.Endpoint.StartsWith("http://"))
{
- var options = apiOptions.SimApiStorageOptions;
- HttpContextAccessor = httpContextAccessor;
- var useSsl = false;
- string endpoint;
- if (options.Endpoint.StartsWith("http://"))
- {
- endpoint = options.Endpoint.Replace("http://", string.Empty);
- }
- else if (options.Endpoint.StartsWith("https://"))
- {
- endpoint = options.Endpoint.Replace("https://", string.Empty);
- useSsl = true;
- }
- else
- {
- throw new Exception("SimApiStorage: Error Endpoint");
- }
-
- ServeUrl = options.ServeUrl;
- Bucket = options.Bucket;
- var mcb = new MinioClient().WithEndpoint(endpoint)
- .WithCredentials(options.AccessKey, options.SecretKey);
- if (useSsl)
- {
- mcb = mcb.WithSSL();
- }
- Mc = mcb.Build();
-
- var found = Mc.BucketExistsAsync(new BucketExistsArgs().WithBucket(Bucket)).Result;
- if (!found)
- {
- Mc.MakeBucketAsync(new MakeBucketArgs().WithBucket(Bucket)).Wait();
- }
+ endpoint = options.Endpoint.Replace("http://", string.Empty);
+ }
+ else if (options.Endpoint.StartsWith("https://"))
+ {
+ endpoint = options.Endpoint.Replace("https://", string.Empty);
+ useSsl = true;
+ }
+ else
+ {
+ throw new Exception("SimApiStorage: Error Endpoint");
}
- ///
- /// 获取上传的URL
- ///
- ///
- ///
- ///
- public string GetUploadUrl(string path, int expire = 7200)
+ ServeUrl = options.ServeUrl;
+ Bucket = options.Bucket;
+ var mcb = new MinioClient().WithEndpoint(endpoint)
+ .WithCredentials(options.AccessKey, options.SecretKey);
+ if (useSsl)
{
- return Mc.PresignedPutObjectAsync(new PresignedPutObjectArgs().WithBucket(Bucket)
- .WithObject(path).WithExpiry(expire)).Result;
+ mcb = mcb.WithSSL();
}
+ Mc = mcb.Build();
- ///
- /// 获取下载的URL
- ///
- ///
- ///
- ///
- public string GetDownloadUrl(string path, int expire = 600)
+ var found = Mc.BucketExistsAsync(new BucketExistsArgs().WithBucket(Bucket)).Result;
+ if (!found)
{
- return Mc.PresignedGetObjectAsync(new PresignedGetObjectArgs().WithBucket(Bucket).WithObject(path)
- .WithExpiry(expire)).Result;
- }
-
-
- public string UploadFile(string path, Stream stream, string contentType = "image/png")
- {
- Mc.PutObjectAsync(new PutObjectArgs().WithBucket(Bucket).WithObject(path).WithObjectSize(stream.Length)
- .WithStreamData(stream).WithContentType(contentType)).Wait();
- return null;
- }
-
- public string FullUrl(string path)
- {
- var httpRequest = HttpContextAccessor.HttpContext?.Request;
- var url = $"{httpRequest?.Scheme}://{httpRequest?.Host}";
- if (string.IsNullOrEmpty(path))
- {
- return path;
- }
-
- return path.StartsWith("~") ? url + path.Substring(1, path.Length - 1) : $"{ServeUrl}{path}";
+ Mc.MakeBucketAsync(new MakeBucketArgs().WithBucket(Bucket)).Wait();
}
}
+
+ ///
+ /// 获取上传的URL
+ ///
+ ///
+ ///
+ ///
+ public string GetUploadUrl(string path, int expire = 7200)
+ {
+ return Mc.PresignedPutObjectAsync(new PresignedPutObjectArgs().WithBucket(Bucket)
+ .WithObject(path).WithExpiry(expire)).Result;
+ }
+
+ ///
+ /// 获取下载的URL
+ ///
+ ///
+ ///
+ ///
+ public string GetDownloadUrl(string path, int expire = 600)
+ {
+ return Mc.PresignedGetObjectAsync(new PresignedGetObjectArgs().WithBucket(Bucket).WithObject(path)
+ .WithExpiry(expire)).Result;
+ }
+
+
+ public string UploadFile(string path, Stream stream, string contentType = "image/png")
+ {
+ Mc.PutObjectAsync(new PutObjectArgs().WithBucket(Bucket).WithObject(path).WithObjectSize(stream.Length)
+ .WithStreamData(stream).WithContentType(contentType)).Wait();
+ return null;
+ }
+
+ public string FullUrl(string path)
+ {
+ var httpRequest = HttpContextAccessor.HttpContext?.Request;
+ var url = $"{httpRequest?.Scheme}://{httpRequest?.Host}";
+ if (string.IsNullOrEmpty(path))
+ {
+ return path;
+ }
+
+ return path.StartsWith('~') ? string.Concat(url, path.AsSpan(1, path.Length - 1)) : $"{ServeUrl}{path}";
+ }
}
\ No newline at end of file
diff --git a/Helpers/SimApiUtil.cs b/Helpers/SimApiUtil.cs
index 14023d2..2f19282 100644
--- a/Helpers/SimApiUtil.cs
+++ b/Helpers/SimApiUtil.cs
@@ -7,69 +7,68 @@ using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Text.Unicode;
-namespace SimApi.Helpers
+namespace SimApi.Helpers;
+
+public static class SimApiUtil
{
- public static class SimApiUtil
+ ///
+ /// 当前CST时间
+ ///
+ public static DateTime CstNow => DateTime.UtcNow.AddHours(8);
+
+ ///
+ /// JSON序列化常规选项
+ ///
+ public static JsonSerializerOptions JsonOption => new()
{
- ///
- /// 当前CST时间
- ///
- public static DateTime CstNow => DateTime.UtcNow.AddHours(8);
+ Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
+ };
- ///
- /// JSON序列化常规选项
- ///
- public static JsonSerializerOptions JsonOption => new()
+ ///
+ /// 当前秒级时间戳
+ ///
+ public static double TimestampNow => (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds;
+
+ ///
+ /// 检测手机号是否正确
+ ///
+ /// 手机号码
+ ///
+ public static bool CheckCell(string cell)
+ {
+ var regex = new Regex("^1[3456789]\\d{9}$");
+ return regex.IsMatch(cell);
+ }
+
+ ///
+ /// MD5加密字符串
+ ///
+ /// 源字符串
+ /// 加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位
+ ///
+ public static string Md5(string source, string mode = "x2")
+ {
+ var sor = Encoding.UTF8.GetBytes(source);
+ var md5 = MD5.Create();
+ var result = md5.ComputeHash(sor);
+ var strbul = new StringBuilder(40);
+ foreach (var t in result)
{
- Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
- PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
- };
-
- ///
- /// 当前秒级时间戳
- ///
- public static double TimestampNow => (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds;
-
- ///
- /// 检测手机号是否正确
- ///
- /// 手机号码
- ///
- public static bool CheckCell(string cell)
- {
- var regex = new Regex("^1[3456789]\\d{9}$");
- return regex.IsMatch(cell);
+ strbul.Append(t.ToString(mode));
}
- ///
- /// MD5加密字符串
- ///
- /// 源字符串
- /// 加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位
- ///
- public static string Md5(string source, string mode = "x2")
- {
- var sor = Encoding.UTF8.GetBytes(source);
- var md5 = MD5.Create();
- var result = md5.ComputeHash(sor);
- var strbul = new StringBuilder(40);
- foreach (var t in result)
- {
- strbul.Append(t.ToString(mode));
- }
+ return strbul.ToString();
+ }
- return strbul.ToString();
- }
-
- ///
- /// 将对象序列化成JSON (控制台输出中文不会被编码)
- ///
- ///
- ///
- public static string Json(object obj)
- {
- return JsonSerializer.Serialize(obj, JsonOption);
- }
+ ///
+ /// 将对象序列化成JSON (控制台输出中文不会被编码)
+ ///
+ ///
+ ///
+ public static string Json(object obj)
+ {
+ return JsonSerializer.Serialize(obj, JsonOption);
}
}
\ No newline at end of file
diff --git a/Logger/SimApiLogger.cs b/Logger/SimApiLogger.cs
index 1fd4c53..a663791 100644
--- a/Logger/SimApiLogger.cs
+++ b/Logger/SimApiLogger.cs
@@ -2,40 +2,32 @@ using System;
using Microsoft.Extensions.Logging;
using SimApi.Helpers;
-namespace SimApi.Logger
+namespace SimApi.Logger;
+
+public class SimApiLogger(string name) : ILogger
{
- public class SimApiLogger : ILogger
+ public IDisposable BeginScope(TState state) => default!;
+
+ public bool IsEnabled(LogLevel logLevel) => true;
+
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception,
+ Func formatter)
{
- private string Name { get; }
-
- public SimApiLogger(string name)
+ Console.ForegroundColor = logLevel switch
{
- Name = name;
- }
-
- public IDisposable BeginScope(TState state) => default!;
-
- public bool IsEnabled(LogLevel logLevel) => true;
-
- public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception,
- Func formatter)
+ LogLevel.Debug => ConsoleColor.DarkMagenta,
+ LogLevel.Information => ConsoleColor.DarkCyan,
+ LogLevel.Warning => ConsoleColor.Yellow,
+ LogLevel.Error => ConsoleColor.Red,
+ LogLevel.Critical => ConsoleColor.DarkRed,
+ _ => ConsoleColor.White
+ };
+ var message =
+ $"[ {name} ][ {SimApiUtil.CstNow.ToString("yyyy-MM-dd HH:mm:ss:ffff")} ][ {logLevel.ToString()} ]\n{state}\n";
+ if (exception != null)
{
- Console.ForegroundColor = logLevel switch
- {
- LogLevel.Debug => ConsoleColor.DarkMagenta,
- LogLevel.Information => ConsoleColor.DarkCyan,
- LogLevel.Warning => ConsoleColor.Yellow,
- LogLevel.Error => ConsoleColor.Red,
- LogLevel.Critical => ConsoleColor.DarkRed,
- _ => ConsoleColor.White
- };
- var message =
- $"[ {Name} ][ {SimApiUtil.CstNow.ToString("yyyy-MM-dd HH:mm:ss:ffff")} ][ {logLevel.ToString()} ]\n{state}\n";
- if (exception != null)
- {
- message += $"{exception}\n";
- }
- Console.WriteLine(message);
+ message += $"{exception}\n";
}
+ Console.WriteLine(message);
}
}
\ No newline at end of file
diff --git a/Logger/SimApiLoggerProvider.cs b/Logger/SimApiLoggerProvider.cs
index 48b0a7d..3225ea2 100644
--- a/Logger/SimApiLoggerProvider.cs
+++ b/Logger/SimApiLoggerProvider.cs
@@ -1,22 +1,20 @@
using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
-namespace SimApi.Logger
+namespace SimApi.Logger;
+
+public class SimApiLoggerProvider : ILoggerProvider
{
- public class SimApiLoggerProvider : ILoggerProvider
+ private readonly ConcurrentDictionary _loggers = new();
+
+
+ public ILogger CreateLogger(string categoryName)
{
- private readonly ConcurrentDictionary _loggers =
- new ConcurrentDictionary();
+ return _loggers.GetOrAdd(categoryName, name => new SimApiLogger(name));
+ }
-
- public ILogger CreateLogger(string categoryName)
- {
- return _loggers.GetOrAdd(categoryName, name => new SimApiLogger(name));
- }
-
- public void Dispose()
- {
- _loggers.Clear();
- }
+ public void Dispose()
+ {
+ _loggers.Clear();
}
}
\ No newline at end of file
diff --git a/Middlewares/SimApiAuthMiddleware.cs b/Middlewares/SimApiAuthMiddleware.cs
index 409db51..8bf4cc0 100644
--- a/Middlewares/SimApiAuthMiddleware.cs
+++ b/Middlewares/SimApiAuthMiddleware.cs
@@ -4,38 +4,30 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using SimApi.Communications;
-namespace SimApi.Middlewares
+namespace SimApi.Middlewares;
+
+///
+/// 认证信息获取中间件
+///
+public class SimApiAuthMiddleware(RequestDelegate next)
{
- ///
- /// 认证信息获取中间件
- ///
- public class SimApiAuthMiddleware
+ public Task Invoke(HttpContext httpContext, IDistributedCache cache)
{
- private RequestDelegate Next { get; }
-
- public SimApiAuthMiddleware(RequestDelegate next)
+ string token = null;
+ if (httpContext.Request.Headers.TryGetValue("Token", out var header))
{
- Next = next;
+ token = header;
}
- public Task Invoke(HttpContext httpContext, IDistributedCache cache)
+ if (!string.IsNullOrEmpty(token))
{
- string token = null;
- if (httpContext.Request.Headers.ContainsKey("Token"))
+ var login = cache.GetString(token);
+ if (login != null)
{
- token = httpContext.Request.Headers["Token"];
+ httpContext.Items.Add("LoginInfo", JsonSerializer.Deserialize(login));
}
-
- if (!string.IsNullOrEmpty(token))
- {
- var login = cache.GetString(token);
- if (login != null)
- {
- httpContext.Items.Add("LoginInfo", JsonSerializer.Deserialize(login));
- }
- }
-
- return Next(httpContext);
}
+
+ return next(httpContext);
}
-}
+}
\ No newline at end of file
diff --git a/Middlewares/SimApiExceptionMiddleware.cs b/Middlewares/SimApiExceptionMiddleware.cs
index 75f8695..10b3cb6 100644
--- a/Middlewares/SimApiExceptionMiddleware.cs
+++ b/Middlewares/SimApiExceptionMiddleware.cs
@@ -6,75 +6,61 @@ using SimApi.Communications;
using Microsoft.Extensions.Logging;
using SimApi.Exceptions;
-namespace SimApi.Middlewares
+namespace SimApi.Middlewares;
+
+///
+/// 异常处理中间件
+///
+public class SimApiExceptionMiddleware(RequestDelegate next, ILogger log)
{
- ///
- /// 异常处理中间件
- ///
- public class SimApiExceptionMiddleware
+ public async Task InvokeAsync(HttpContext context)
{
- private RequestDelegate Next { get; }
-
- private ILogger Log { get; }
-
- public SimApiExceptionMiddleware(RequestDelegate next, ILogger log)
+ if (context.Request.Headers.TryGetValue("Query-Id", out var header))
{
- Log = log;
- Next = next;
+ context.Response.Headers["Query-Id"] = header;
}
- public async Task InvokeAsync(HttpContext context)
+ SimApiBaseResponse response;
+ try
{
- if (context.Request.Headers.ContainsKey("Query-Id"))
+ await next(context);
+ if (context.Response.StatusCode != 200)
{
- context.Response.Headers["Query-Id"] = context.Request.Headers["Query-Id"];
- }
-
- var response = new SimApiBaseResponse();
- try
- {
- await Next(context);
- if (context.Response.StatusCode != 200)
+ if (!new[] { 301, 302 }.Contains(context.Response.StatusCode))
{
- if (!new[]
- {
- 301, 302
- }.Contains(context.Response.StatusCode))
- {
- throw new SimApiException(context.Response.StatusCode);
- }
+ throw new SimApiException(context.Response.StatusCode);
}
}
- catch (SimApiException ex)
- {
- response = string.IsNullOrEmpty(ex.Message)
- ? new SimApiBaseResponse(ex.Code)
- : new SimApiBaseResponse(ex.Code, ex.Message);
-
- ErrorResponse(context, response);
- }
- catch (Exception ex)
- {
- Log.LogError(ex.Message);
- Log.LogError(ex.StackTrace);
- response = new SimApiBaseResponse(500, ex.Message);
- ErrorResponse(context, response);
- }
}
-
- ///
- /// 异常抛出错误
- ///
- ///
- ///
- private void ErrorResponse(HttpContext context, SimApiBaseResponse response)
+ catch (SimApiException ex)
{
- if (!context.Response.HasStarted)
- {
- context.Response.StatusCode = 200;
- context.Response.Headers.Add("Content-Type", "application/json");
- context.Response.WriteAsync(response.ToString());
- }
+ response = string.IsNullOrEmpty(ex.Message)
+ ? new SimApiBaseResponse(ex.Code)
+ : new SimApiBaseResponse(ex.Code, ex.Message);
+
+ ErrorResponse(context, response);
+ }
+ catch (Exception ex)
+ {
+ log.LogError(ex.Message);
+ log.LogError(ex.StackTrace);
+ response = new SimApiBaseResponse(500, ex.Message);
+ ErrorResponse(context, response);
+ }
+ }
+
+ ///
+ /// 异常抛出错误
+ ///
+ ///
+ ///
+ private void ErrorResponse(HttpContext context, SimApiBaseResponse response)
+ {
+ if (!context.Response.HasStarted)
+ {
+ context.Response.StatusCode = 200;
+ context.Response.Headers.Append("Content-Type", "application/json");
+ context.Response.WriteAsync(response.ToString());
}
}
}
\ No newline at end of file
diff --git a/Models/SimApiBaseModel.cs b/Models/SimApiBaseModel.cs
index 790491e..6c42a57 100644
--- a/Models/SimApiBaseModel.cs
+++ b/Models/SimApiBaseModel.cs
@@ -1,91 +1,89 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
-using System.Text.Json;
using SimApi.Helpers;
-namespace SimApi.Models
+namespace SimApi.Models;
+
+public class SimApiBaseModel
{
- public class SimApiBaseModel
+ [Column(Order = 1)]
+ public string Id { get; set; } = Guid.NewGuid().ToString();
+
+ [Column(Order = 9998)]
+ public DateTime UpdatedAt { get; set; } = SimApiUtil.CstNow;
+
+ [Column(Order = 9999)]
+ public DateTime CreatedAt { get; set; } = SimApiUtil.CstNow;
+
+ protected virtual string[] MapperIgnoreField { get; set; } = { "Id", "CreatedAt", "UpdatedAt" };
+
+ protected virtual string UpdatedTimeField { get; set; } = "UpdatedAt";
+
+ public void MapData(TS source, bool mapAll = false)
{
- [Column(Order = 1)]
- public string Id { get; set; } = Guid.NewGuid().ToString();
-
- [Column(Order = 9998)]
- public DateTime UpdatedAt { get; set; } = SimApiUtil.CstNow;
-
- [Column(Order = 9999)]
- public DateTime CreatedAt { get; set; } = SimApiUtil.CstNow;
-
- protected virtual string[] MapperIgnoreField { get; set; } = { "Id", "CreatedAt", "UpdatedAt" };
-
- protected virtual string UpdatedTimeField { get; set; } = "UpdatedAt";
-
- public void MapData(TS source, bool mapAll = false)
- {
- //获取要赋值的源数据不为null的项目
- var sourceProps = source.GetType().GetProperties().Where(x => x.GetValue(source) != null)
- .Select(x => new
- {
- x.Name,
- x.PropertyType
- })
- .ToDictionary(x => x.Name, x => x.PropertyType);
-
- //获取目标对象的属性信息
- var targetProps = GetType().GetProperties().Select(x => new
- {
- x.Name,
- x.PropertyType
- })
- .ToDictionary(x => x.Name, x => x.PropertyType);
- foreach (var sp in sourceProps.Where(sp =>
- targetProps.ContainsKey(sp.Key) && sp.Value == targetProps[sp.Key] &&
- (!MapperIgnoreField.Contains(sp.Key) || mapAll)))
+ //获取要赋值的源数据不为null的项目
+ var sourceProps = source.GetType().GetProperties().Where(x => x.GetValue(source) != null)
+ .Select(x => new
{
- GetType().GetProperty(sp.Key)?
- .SetValue(this, source.GetType().GetProperty(sp.Key)?.GetValue(source));
- }
+ x.Name,
+ x.PropertyType
+ })
+ .ToDictionary(x => x.Name, x => x.PropertyType);
- UpdateTime();
- }
-
- public void MapData(TS source, string[] mapFields)
- {
- //获取要赋值的源数据不为null的项目
- var sourceProps = source.GetType().GetProperties().Where(x => x.GetValue(source) != null)
- .Select(x => new
- {
- x.Name,
- x.PropertyType
- })
- .ToDictionary(x => x.Name, x => x.PropertyType);
-
- //获取目标对象的属性信息
- var targetProps = GetType().GetProperties().Select(x => new
- {
- x.Name,
- x.PropertyType
- })
- .ToDictionary(x => x.Name, x => x.PropertyType);
- foreach (var sp in sourceProps.Where(sp =>
- targetProps.ContainsKey(sp.Key) && sp.Value == targetProps[sp.Key] &&
- mapFields.Contains(sp.Key)))
+ //获取目标对象的属性信息
+ var targetProps = GetType().GetProperties().Select(x => new
{
- GetType().GetProperty(sp.Key)?
- .SetValue(this, source.GetType().GetProperty(sp.Key)?.GetValue(source));
- }
-
- UpdateTime();
- }
-
- ///
- /// 更新update时间
- ///
- ///
- public void UpdateTime()
+ x.Name,
+ x.PropertyType
+ })
+ .ToDictionary(x => x.Name, x => x.PropertyType);
+ foreach (var sp in sourceProps.Where(sp =>
+ targetProps.ContainsKey(sp.Key) && sp.Value == targetProps[sp.Key] &&
+ (!MapperIgnoreField.Contains(sp.Key) || mapAll)))
{
- GetType().GetProperty(UpdatedTimeField)?.SetValue(this, SimApiUtil.CstNow);
+ GetType().GetProperty(sp.Key)?
+ .SetValue(this, source.GetType().GetProperty(sp.Key)?.GetValue(source));
}
+
+ UpdateTime();
+ }
+
+ public void MapData(TS source, string[] mapFields)
+ {
+ //获取要赋值的源数据不为null的项目
+ var sourceProps = source.GetType().GetProperties().Where(x => x.GetValue(source) != null)
+ .Select(x => new
+ {
+ x.Name,
+ x.PropertyType
+ })
+ .ToDictionary(x => x.Name, x => x.PropertyType);
+
+ //获取目标对象的属性信息
+ var targetProps = GetType().GetProperties().Select(x => new
+ {
+ x.Name,
+ x.PropertyType
+ })
+ .ToDictionary(x => x.Name, x => x.PropertyType);
+ foreach (var sp in sourceProps.Where(sp =>
+ targetProps.ContainsKey(sp.Key) && sp.Value == targetProps[sp.Key] &&
+ mapFields.Contains(sp.Key)))
+ {
+ GetType().GetProperty(sp.Key)?
+ .SetValue(this, source.GetType().GetProperty(sp.Key)?.GetValue(source));
+ }
+
+ UpdateTime();
+ }
+
+ ///
+ /// 更新update时间
+ ///
+ ///
+ public void UpdateTime()
+ {
+ GetType().GetProperty(UpdatedTimeField)?.SetValue(this, SimApiUtil.CstNow);
}
}
\ No newline at end of file
diff --git a/SimApi.csproj b/SimApi.csproj
index 1c593b9..9853b60 100644
--- a/SimApi.csproj
+++ b/SimApi.csproj
@@ -1,42 +1,42 @@
-
- Library
- true
- 0.2.3
- xRain@SimcuTeam
- AspNetCore一个方便的API文档,捕获异常,统一输入输出的API类库
- Simcu.SimApi
- true
- snupkg
- true
- 5.0.0
- false
- true
- 5.0.2
- net7.0;net8.0
-
+
+ Library
+ true
+ 0.2.3
+ xRain@SimcuTeam
+ AspNetCore一个方便的API文档,捕获异常,统一输入输出的API类库
+ Simcu.SimApi
+ true
+ snupkg
+ true
+ 5.0.0
+ false
+ true
+ 5.0.2
+ net8.0
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SimApiExtensions.cs b/SimApiExtensions.cs
index ce2e3da..e4b62f5 100644
--- a/SimApiExtensions.cs
+++ b/SimApiExtensions.cs
@@ -9,257 +9,256 @@ using Microsoft.Extensions.Logging;
using SimApi.Configs;
using SimApi.Logger;
-namespace SimApi
+namespace SimApi;
+
+///
+/// 加入系统的扩展信息
+///
+public static class SimApiExtensions
{
- ///
- /// 加入系统的扩展信息
- ///
- public static class SimApiExtensions
+ //**********快捷添加**************
+ public static IServiceCollection AddSimApi(this IServiceCollection builder,
+ Action options = null)
{
- //**********快捷添加**************
- public static IServiceCollection AddSimApi(this IServiceCollection builder,
- Action options = null)
+ var simApiOptions = new SimApiOptions();
+ options?.Invoke(simApiOptions);
+ if (simApiOptions.EnableLogger)
{
- var simApiOptions = new SimApiOptions();
- options?.Invoke(simApiOptions);
- if (simApiOptions.EnableLogger)
+ builder.AddLogging(logger =>
{
- builder.AddLogging(logger =>
+ logger.ClearProviders();
+ logger.AddProvider(new SimApiLoggerProvider());
+ });
+ }
+ // 是否使用 AUTH
+ if (simApiOptions.EnableSimApiAuth)
+ {
+ builder.AddScoped();
+ }
+
+ if (simApiOptions.EnableCors)
+ {
+ builder.AddCors(cors => cors.AddPolicy("any",
+ policy => { policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin(); }));
+ }
+
+ if (simApiOptions.EnableSynapse)
+ {
+ builder.AddSingleton();
+ }
+
+ // 使用SimApiDoc
+ if (simApiOptions.EnableSimApiDoc)
+ {
+ var docOptions = simApiOptions.SimApiDocOptions;
+ builder.AddSwaggerGen(x =>
+ {
+ foreach (var group in docOptions.ApiGroups)
{
- logger.ClearProviders();
- logger.AddProvider(new SimApiLoggerProvider());
- });
- }
- // 是否使用 AUTH
- if (simApiOptions.EnableSimApiAuth)
- {
- builder.AddScoped();
- }
+ x.SwaggerDoc(group.Id, new OpenApiInfo
+ {
+ Title = group.Name,
+ Description = group.Description
+ });
+ }
- if (simApiOptions.EnableCors)
- {
- builder.AddCors(cors => cors.AddPolicy("any",
- policy => { policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin(); }));
- }
-
- if (simApiOptions.EnableSynapse)
- {
- builder.AddSingleton();
- }
-
- // 使用SimApiDoc
- if (simApiOptions.EnableSimApiDoc)
- {
- var docOptions = simApiOptions.SimApiDocOptions;
- builder.AddSwaggerGen(x =>
+ x.EnableAnnotations();
+ var haveOauth = false;
+ var haveSimApiAuth = false;
+ var oauthFlows = new OpenApiOAuthFlows();
+ foreach (var auth in docOptions.ApiAuth.Type)
{
- foreach (var group in docOptions.ApiGroups)
+ switch (auth)
{
- x.SwaggerDoc(group.Id, new OpenApiInfo
- {
- Title = group.Name,
- Description = group.Description
- });
- }
-
- x.EnableAnnotations();
- var haveOauth = false;
- var haveSimApiAuth = false;
- var oauthFlows = new OpenApiOAuthFlows();
- foreach (var auth in docOptions.ApiAuth.Type)
- {
- switch (auth)
- {
- case "SimApiAuth":
- x.AddSecurityRequirement(new OpenApiSecurityRequirement
- {
- {
- new OpenApiSecurityScheme
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.SecurityScheme,
- Id = "HeaderToken"
- }
- },
- new[] { "readAccess", "writeAccess" }
- }
- });
- haveSimApiAuth = true;
- break;
- case "ClientCredentials":
- oauthFlows.ClientCredentials = new OpenApiOAuthFlow
- {
- TokenUrl = new Uri(docOptions.ApiAuth.TokenUrl, UriKind.RelativeOrAbsolute),
- Scopes = docOptions.ApiAuth.Scopes
- };
- haveOauth = true;
- break;
- case "Implicit":
- oauthFlows.Implicit = new OpenApiOAuthFlow
- {
- AuthorizationUrl = new Uri(docOptions.ApiAuth.AuthorizationUrl,
- UriKind.RelativeOrAbsolute),
- Scopes = docOptions.ApiAuth.Scopes
- };
- haveOauth = true;
- break;
- case "AuthorizationCode":
- oauthFlows.AuthorizationCode = new OpenApiOAuthFlow
- {
- TokenUrl = new Uri(docOptions.ApiAuth.TokenUrl, UriKind.RelativeOrAbsolute),
- AuthorizationUrl = new Uri(docOptions.ApiAuth.AuthorizationUrl,
- UriKind.RelativeOrAbsolute),
- Scopes = docOptions.ApiAuth.Scopes
- };
- haveOauth = true;
- break;
- case "Password":
- oauthFlows.Password = new OpenApiOAuthFlow
- {
- TokenUrl = new Uri(docOptions.ApiAuth.TokenUrl, UriKind.RelativeOrAbsolute),
- Scopes = docOptions.ApiAuth.Scopes
- };
- haveOauth = true;
- break;
- }
- }
-
- if (haveOauth)
- {
- x.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
- {
- Type = SecuritySchemeType.OAuth2,
- Flows = oauthFlows,
- Description = docOptions.ApiAuth.Description,
- In = ParameterLocation.Header
- });
- x.AddSecurityRequirement(new OpenApiSecurityRequirement
- {
+ case "SimApiAuth":
+ x.AddSecurityRequirement(new OpenApiSecurityRequirement
{
- new OpenApiSecurityScheme
{
- Reference = new OpenApiReference
+ new OpenApiSecurityScheme
{
- Type = ReferenceType.SecurityScheme,
- Id = "oauth2"
- }
- },
- new[] { "SimApiAuth" }
- }
- });
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "HeaderToken"
+ }
+ },
+ new[] { "readAccess", "writeAccess" }
+ }
+ });
+ haveSimApiAuth = true;
+ break;
+ case "ClientCredentials":
+ oauthFlows.ClientCredentials = new OpenApiOAuthFlow
+ {
+ TokenUrl = new Uri(docOptions.ApiAuth.TokenUrl, UriKind.RelativeOrAbsolute),
+ Scopes = docOptions.ApiAuth.Scopes
+ };
+ haveOauth = true;
+ break;
+ case "Implicit":
+ oauthFlows.Implicit = new OpenApiOAuthFlow
+ {
+ AuthorizationUrl = new Uri(docOptions.ApiAuth.AuthorizationUrl,
+ UriKind.RelativeOrAbsolute),
+ Scopes = docOptions.ApiAuth.Scopes
+ };
+ haveOauth = true;
+ break;
+ case "AuthorizationCode":
+ oauthFlows.AuthorizationCode = new OpenApiOAuthFlow
+ {
+ TokenUrl = new Uri(docOptions.ApiAuth.TokenUrl, UriKind.RelativeOrAbsolute),
+ AuthorizationUrl = new Uri(docOptions.ApiAuth.AuthorizationUrl,
+ UriKind.RelativeOrAbsolute),
+ Scopes = docOptions.ApiAuth.Scopes
+ };
+ haveOauth = true;
+ break;
+ case "Password":
+ oauthFlows.Password = new OpenApiOAuthFlow
+ {
+ TokenUrl = new Uri(docOptions.ApiAuth.TokenUrl, UriKind.RelativeOrAbsolute),
+ Scopes = docOptions.ApiAuth.Scopes
+ };
+ haveOauth = true;
+ break;
}
+ }
- if (haveSimApiAuth)
+ if (haveOauth)
+ {
+ x.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
- x.AddSecurityDefinition("HeaderToken",
+ Type = SecuritySchemeType.OAuth2,
+ Flows = oauthFlows,
+ Description = docOptions.ApiAuth.Description,
+ In = ParameterLocation.Header
+ });
+ x.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
new OpenApiSecurityScheme
{
- Name = "Token",
- In = ParameterLocation.Header
- });
- }
- });
- }
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "oauth2"
+ }
+ },
+ new[] { "SimApiAuth" }
+ }
+ });
+ }
- // 使用Header转发,应对代理后获取真实ip
- if (simApiOptions.EnableForwardHeaders)
- {
- builder.Configure(fwOptions =>
+ if (haveSimApiAuth)
{
- fwOptions.ForwardedHeaders = ForwardedHeaders.All;
- fwOptions.KnownNetworks.Clear();
- fwOptions.KnownProxies.Clear();
- });
- }
-
- if (simApiOptions.EnableLowerUrl)
- {
- builder.AddRouting(rOptions => rOptions.LowercaseUrls = true);
- }
-
- if (simApiOptions.EnableSimApiStorage)
- {
- builder.AddHttpContextAccessor();
- builder.AddSingleton();
- }
-
- builder.AddSingleton(simApiOptions);
- return builder;
+ x.AddSecurityDefinition("HeaderToken",
+ new OpenApiSecurityScheme
+ {
+ Name = "Token",
+ In = ParameterLocation.Header
+ });
+ }
+ });
}
- ///
- /// 使用所有SimApi自定义中间件
- ///
- ///
- ///
- public static IApplicationBuilder UseSimApi(this IApplicationBuilder builder)
+ // 使用Header转发,应对代理后获取真实ip
+ if (simApiOptions.EnableForwardHeaders)
{
- var options = builder.ApplicationServices.GetRequiredService();
-
- var logger = builder.ApplicationServices.GetRequiredService>();
-
- if (options.EnableForwardHeaders)
+ builder.Configure(fwOptions =>
{
- logger.LogInformation("开始配置ForwardedHeaders...");
- builder.UseForwardedHeaders();
- }
-
- if (options.EnableCors)
- {
- logger.LogInformation("开始配置Cors全部允许...");
- builder.UseCors("any");
- }
-
- if (options.EnableSimApiAuth)
- {
- logger.LogInformation("开始配置SimApiAuth...");
- builder.UseMiddleware();
- }
-
- if (options.EnableSimApiDoc)
- {
- logger.LogInformation("开始配置SimApiDoc...");
- var docOptions = options.SimApiDocOptions;
- builder.UseSwagger(x => x.RouteTemplate = "/swagger/{documentName}.json").UseSwaggerUI(x =>
- {
- x.DocumentTitle = docOptions.DocumentTitle;
- foreach (var group in docOptions.ApiGroups)
- {
- x.SwaggerEndpoint($"/swagger/{group.Id}.json", name: group.Name);
- }
-
- x.EnableValidator();
- x.SupportedSubmitMethods(docOptions.SupportedMethod);
- x.DisplayRequestDuration();
- });
- }
-
- if (options.EnableSimApiException)
- {
- logger.LogInformation("开始配置SimApiException...");
- builder.UseMiddleware();
- }
-
- //请求一下检测存储错误
- if (options.EnableSimApiStorage)
- {
- logger.LogInformation("开始配置SimApiStorage...");
- builder.ApplicationServices.GetService();
- }
-
- if (options.EnableLowerUrl)
- {
- logger.LogInformation("开始配置使用URL小写...");
- }
-
- if (options.EnableSynapse)
- {
- var synapse = builder.ApplicationServices.GetRequiredService();
- synapse.Init();
- }
-
- return builder;
+ fwOptions.ForwardedHeaders = ForwardedHeaders.All;
+ fwOptions.KnownNetworks.Clear();
+ fwOptions.KnownProxies.Clear();
+ });
}
+
+ if (simApiOptions.EnableLowerUrl)
+ {
+ builder.AddRouting(rOptions => rOptions.LowercaseUrls = true);
+ }
+
+ if (simApiOptions.EnableSimApiStorage)
+ {
+ builder.AddHttpContextAccessor();
+ builder.AddSingleton();
+ }
+
+ builder.AddSingleton(simApiOptions);
+ return builder;
+ }
+
+ ///
+ /// 使用所有SimApi自定义中间件
+ ///
+ ///
+ ///
+ public static IApplicationBuilder UseSimApi(this IApplicationBuilder builder)
+ {
+ var options = builder.ApplicationServices.GetRequiredService();
+
+ var logger = builder.ApplicationServices.GetRequiredService>();
+
+ if (options.EnableForwardHeaders)
+ {
+ logger.LogInformation("开始配置ForwardedHeaders...");
+ builder.UseForwardedHeaders();
+ }
+
+ if (options.EnableCors)
+ {
+ logger.LogInformation("开始配置Cors全部允许...");
+ builder.UseCors("any");
+ }
+
+ if (options.EnableSimApiAuth)
+ {
+ logger.LogInformation("开始配置SimApiAuth...");
+ builder.UseMiddleware();
+ }
+
+ if (options.EnableSimApiDoc)
+ {
+ logger.LogInformation("开始配置SimApiDoc...");
+ var docOptions = options.SimApiDocOptions;
+ builder.UseSwagger(x => x.RouteTemplate = "/swagger/{documentName}.json").UseSwaggerUI(x =>
+ {
+ x.DocumentTitle = docOptions.DocumentTitle;
+ foreach (var group in docOptions.ApiGroups)
+ {
+ x.SwaggerEndpoint($"/swagger/{group.Id}.json", name: group.Name);
+ }
+
+ x.EnableValidator();
+ x.SupportedSubmitMethods(docOptions.SupportedMethod);
+ x.DisplayRequestDuration();
+ });
+ }
+
+ if (options.EnableSimApiException)
+ {
+ logger.LogInformation("开始配置SimApiException...");
+ builder.UseMiddleware();
+ }
+
+ //请求一下检测存储错误
+ if (options.EnableSimApiStorage)
+ {
+ logger.LogInformation("开始配置SimApiStorage...");
+ builder.ApplicationServices.GetService();
+ }
+
+ if (options.EnableLowerUrl)
+ {
+ logger.LogInformation("开始配置使用URL小写...");
+ }
+
+ if (options.EnableSynapse)
+ {
+ var synapse = builder.ApplicationServices.GetRequiredService();
+ synapse.Init();
+ }
+
+ return builder;
}
}
\ No newline at end of file