csharp-sdk-upm/Engine/Internal/Controllers/LCFunctionController.cs

100 lines
3.6 KiB
C#

using System;
using System.Text.Json;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Cors;
using LeanCloud.Storage;
using LeanCloud.Storage.Internal.Codec;
namespace LeanCloud.Engine {
[ApiController]
[Route("{1,1.1}")]
[EnableCors(LCEngine.LCEngineCORS)]
public class LCFunctionController : ControllerBase {
private Dictionary<string, MethodInfo> Functions => LCEngine.Functions;
[HttpGet("functions/_ops/metadatas")]
public object GetFunctions() {
try {
return LCEngine.GetFunctions(Request);
} catch (Exception e) {
return StatusCode(500, e.Message);
}
}
[HttpPost("functions/{funcName}")]
public async Task<object> Run(string funcName, JsonElement body) {
try {
LCLogger.Debug($"Run: {funcName}");
LCLogger.Debug(body.ToString());
if (Functions.TryGetValue(funcName, out MethodInfo mi)) {
LCEngine.InitRequestContext(Request);
object[] ps = ParseParameters(mi, body);
object result = await LCEngine.Invoke(mi, ps.ToArray());
if (result != null) {
return new Dictionary<string, object> {
{ "result", result }
};
}
}
return body;
} catch (Exception e) {
return StatusCode(500, e.Message);
}
}
[HttpPost("call/{funcName}")]
public async Task<object> RPC(string funcName, JsonElement body) {
try {
LCLogger.Debug($"RPC: {funcName}");
LCLogger.Debug(body.ToString());
if (Functions.TryGetValue(funcName, out MethodInfo mi)) {
LCEngine.InitRequestContext(Request);
object[] ps = ParseParameters(mi, body);
object result = await LCEngine.Invoke(mi, ps);
if (result != null) {
return new Dictionary<string, object> {
{ "result", LCCloud.Encode(result) }
};
}
}
return body;
} catch (Exception e) {
return StatusCode(500, e.Message);
}
}
private static object[] ParseParameters(MethodInfo mi, JsonElement body) {
Dictionary<string, object> parameters = LCEngine.Decode(body);
List<object> ps = new List<object>();
if (mi.GetParameters().Length > 0) {
if (Array.Exists(mi.GetParameters(),
p => p.GetCustomAttribute<LCEngineFunctionParamAttribute>() != null)) {
// 如果包含 LCEngineFunctionParamAttribute 的参数,则按照配对方式传递参数
foreach (ParameterInfo pi in mi.GetParameters()) {
LCEngineFunctionParamAttribute attr = pi.GetCustomAttribute<LCEngineFunctionParamAttribute>();
if (attr != null) {
string paramName = attr.ParamName;
ps.Add(parameters[paramName]);
}
}
} else {
ps.Add(LCDecoder.Decode(LCEngine.Decode(body)));
}
}
return ps.ToArray();
}
}
}