Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e53048a980 | ||
|
|
bbc2806995 | ||
|
|
404a638d5e | ||
|
|
e27d5e1c77 | ||
|
|
6af68da3eb |
@@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SimApi.Attributes;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class OriginResponseAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using SimApi.Helpers;
|
||||||
|
|
||||||
namespace SimApi.Communications;
|
namespace SimApi.Communications;
|
||||||
|
|
||||||
@@ -36,15 +37,7 @@ public class SimApiBaseResponse(int code = 200, string message = "成功")
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(this, new JsonSerializerOptions
|
return SimApiUtil.Json(this);
|
||||||
{
|
|
||||||
IgnoreReadOnlyProperties = true,
|
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
||||||
Converters =
|
|
||||||
{
|
|
||||||
new JsonStringEnumConverter()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ public class SimApiOptions
|
|||||||
/// default: true
|
/// default: true
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnableSimApiException { get; set; } = true;
|
public bool EnableSimApiException { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启用返回结果拦截
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableSimApiResponseFilter { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开启S3兼容的存储系统。
|
/// 开启S3兼容的存储系统。
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using SimApi.Attributes;
|
||||||
|
using SimApi.Communications;
|
||||||
|
|
||||||
|
namespace SimApi.Helpers;
|
||||||
|
|
||||||
|
public class SimApiResponseFilter : IResultFilter
|
||||||
|
{
|
||||||
|
public void OnResultExecuting(ResultExecutingContext context)
|
||||||
|
{
|
||||||
|
if (context.ActionDescriptor.EndpointMetadata.Any(meta => meta is OriginResponseAttribute))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Result = context.Result switch
|
||||||
|
{
|
||||||
|
// 检查结果是否为 null
|
||||||
|
null => new OkObjectResult(new SimApiBaseResponse()),
|
||||||
|
ObjectResult { Value: SimApiBaseResponse simApiBaseResponse } =>
|
||||||
|
new OkObjectResult(simApiBaseResponse),
|
||||||
|
ObjectResult objectResult => new OkObjectResult(new SimApiBaseResponse<object>(objectResult.Value!)),
|
||||||
|
EmptyResult => new OkObjectResult(new SimApiBaseResponse()),
|
||||||
|
_ => context.Result
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnResultExecuted(ResultExecutedContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using SimApi.Communications;
|
using SimApi.Communications;
|
||||||
@@ -27,12 +27,11 @@ public class SimApiExceptionMiddleware(RequestDelegate next, ILogger<SimApiExcep
|
|||||||
switch (context.Response.StatusCode)
|
switch (context.Response.StatusCode)
|
||||||
{
|
{
|
||||||
case 200:
|
case 200:
|
||||||
break;
|
|
||||||
case 404:
|
|
||||||
throw new SimApiException(context.Response.StatusCode, "请求的接口不存在");
|
|
||||||
case 301:
|
case 301:
|
||||||
case 302:
|
case 302:
|
||||||
break;
|
break;
|
||||||
|
case 404:
|
||||||
|
throw new SimApiException(context.Response.StatusCode, "请求的接口不存在");
|
||||||
default:
|
default:
|
||||||
throw new SimApiException(context.Response.StatusCode);
|
throw new SimApiException(context.Response.StatusCode);
|
||||||
}
|
}
|
||||||
@@ -42,7 +41,6 @@ public class SimApiExceptionMiddleware(RequestDelegate next, ILogger<SimApiExcep
|
|||||||
response = string.IsNullOrEmpty(ex.Message)
|
response = string.IsNullOrEmpty(ex.Message)
|
||||||
? new SimApiBaseResponse(ex.Code)
|
? new SimApiBaseResponse(ex.Code)
|
||||||
: new SimApiBaseResponse(ex.Code, ex.Message);
|
: new SimApiBaseResponse(ex.Code, ex.Message);
|
||||||
|
|
||||||
ErrorResponse(context, response);
|
ErrorResponse(context, response);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -61,9 +59,8 @@ public class SimApiExceptionMiddleware(RequestDelegate next, ILogger<SimApiExcep
|
|||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
private static void ErrorResponse(HttpContext context, SimApiBaseResponse response)
|
private static void ErrorResponse(HttpContext context, SimApiBaseResponse response)
|
||||||
{
|
{
|
||||||
if (context.Response.HasStarted) return;
|
|
||||||
context.Response.StatusCode = 200;
|
context.Response.StatusCode = 200;
|
||||||
context.Response.Headers.Append("Content-Type", "application/json");
|
context.Response.Headers.Append("Content-Type", "application/json");
|
||||||
context.Response.WriteAsync(response.ToString());
|
context.Response.WriteAsync(response.ToString()).Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,9 +19,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Helpers\"/>
|
|
||||||
<Folder Include="Communications\"/>
|
<Folder Include="Communications\"/>
|
||||||
<Folder Include="Middlewares\"/>
|
|
||||||
<Folder Include="Exceptions\"/>
|
<Folder Include="Exceptions\"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.Json;
|
||||||
using SimApi.Helpers;
|
using SimApi.Helpers;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -7,6 +11,7 @@ using SimApi.Middlewares;
|
|||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SimApi.Attributes;
|
||||||
using SimApi.CoceSdk;
|
using SimApi.CoceSdk;
|
||||||
using SimApi.Configurations;
|
using SimApi.Configurations;
|
||||||
using SimApi.Logger;
|
using SimApi.Logger;
|
||||||
@@ -53,6 +58,19 @@ public static class SimApiExtensions
|
|||||||
if (simApiOptions.EnableSynapse)
|
if (simApiOptions.EnableSynapse)
|
||||||
{
|
{
|
||||||
builder.AddSingleton<Synapse>();
|
builder.AddSingleton<Synapse>();
|
||||||
|
//自动依赖注入
|
||||||
|
var stackTrace = new StackTrace();
|
||||||
|
var callingMethod = stackTrace.GetFrame(stackTrace.FrameCount - 1)?.GetMethod();
|
||||||
|
var assembly = callingMethod?.DeclaringType?.Assembly;
|
||||||
|
var types = assembly?.GetTypes() ?? [];
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
var methodsWithSynapse = type.GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttribute<SynapseRpcAttribute>() != null ||
|
||||||
|
m.GetCustomAttribute<SynapseEventAttribute>() != null);
|
||||||
|
if (!methodsWithSynapse.Any()) continue;
|
||||||
|
builder.AddScoped(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用SimApiDoc
|
// 使用SimApiDoc
|
||||||
@@ -192,6 +210,12 @@ public static class SimApiExtensions
|
|||||||
builder.AddSingleton<SimApiStorage>();
|
builder.AddSingleton<SimApiStorage>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (simApiOptions.EnableSimApiResponseFilter)
|
||||||
|
{
|
||||||
|
builder.AddControllers(opt => opt.Filters.Add<SimApiResponseFilter>())
|
||||||
|
.AddJsonOptions(opt => opt.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase);
|
||||||
|
}
|
||||||
|
|
||||||
builder.AddSingleton(simApiOptions);
|
builder.AddSingleton(simApiOptions);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
@@ -211,6 +235,11 @@ public static class SimApiExtensions
|
|||||||
builder.Services.GetService<SimApiStorage>();
|
builder.Services.GetService<SimApiStorage>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.EnableSimApiResponseFilter)
|
||||||
|
{
|
||||||
|
logger.LogInformation("开始配置SimApiResponseFilter...");
|
||||||
|
}
|
||||||
|
|
||||||
if (options.EnableCoceSdk)
|
if (options.EnableCoceSdk)
|
||||||
{
|
{
|
||||||
logger.LogInformation("开始配置CoceAppSdk...\nApi入口: {ApiUrl}\nAuth入口:{AuthUrl}n\nAppId: {AppId}",
|
logger.LogInformation("开始配置CoceAppSdk...\nApi入口: {ApiUrl}\nAuth入口:{AuthUrl}n\nAppId: {AppId}",
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ public partial class Synapse
|
|||||||
Client!.SubscribeAsync(rcSubOpts).Wait();
|
Client!.SubscribeAsync(rcSubOpts).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? FireRpc(string app, string action, object? param, Dictionary<string, string>? headers = null)
|
private string? FireRpc(string app, string action, object? param, Dictionary<string, string>? headers = null,
|
||||||
|
int? timeout = null)
|
||||||
{
|
{
|
||||||
string paramJson;
|
string paramJson;
|
||||||
if (param is string strParam)
|
if (param is string strParam)
|
||||||
@@ -77,7 +78,8 @@ public partial class Synapse
|
|||||||
string response;
|
string response;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (tcs.Task.Wait(Options.RpcTimeout * 1000))
|
timeout ??= Options.RpcTimeout;
|
||||||
|
if (tcs.Task.Wait(timeout.Value * 1000))
|
||||||
{
|
{
|
||||||
response = tcs.Task.Result;
|
response = tcs.Task.Result;
|
||||||
logger.LogDebug(
|
logger.LogDebug(
|
||||||
|
|||||||
+6
-4
@@ -88,10 +88,11 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
|
|||||||
/// <param name="method"></param>
|
/// <param name="method"></param>
|
||||||
/// <param name="param"></param>
|
/// <param name="param"></param>
|
||||||
/// <param name="headers"></param>
|
/// <param name="headers"></param>
|
||||||
|
/// <param name="timeout"></param>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public SimApiBaseResponse<T> Rpc<T>(string appName, string method, dynamic? param = null,
|
public SimApiBaseResponse<T> Rpc<T>(string appName, string method, dynamic? param = null,
|
||||||
Dictionary<string, string>? headers = null)
|
Dictionary<string, string>? headers = null, int? timeout = null)
|
||||||
{
|
{
|
||||||
var res = new SimApiBaseResponse(500, "Synapse Rpc Client Disabled!");
|
var res = new SimApiBaseResponse(500, "Synapse Rpc Client Disabled!");
|
||||||
if (Options.DisableRpcClient)
|
if (Options.DisableRpcClient)
|
||||||
@@ -100,7 +101,7 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var data = FireRpc(appName, method, param, headers);
|
var data = FireRpc(appName, method, param, headers, timeout);
|
||||||
res = JsonSerializer.Deserialize<SimApiBaseResponse<T>>(data, SimApiUtil.JsonOption);
|
res = JsonSerializer.Deserialize<SimApiBaseResponse<T>>(data, SimApiUtil.JsonOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,11 +115,12 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
|
|||||||
/// <param name="method"></param>
|
/// <param name="method"></param>
|
||||||
/// <param name="param"></param>
|
/// <param name="param"></param>
|
||||||
/// <param name="headers"></param>
|
/// <param name="headers"></param>
|
||||||
|
/// <param name="timeout"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public SimApiBaseResponse<object> Rpc(string appName, string method, dynamic? param = null,
|
public SimApiBaseResponse<object> Rpc(string appName, string method, dynamic? param = null,
|
||||||
Dictionary<string, string>? headers = null)
|
Dictionary<string, string>? headers = null, int? timeout = null)
|
||||||
{
|
{
|
||||||
return Rpc<object>(appName, method, param, headers);
|
return Rpc<object>(appName, method, param, headers, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user