2021-03-19 17:02:57 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Text.Json;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Reflection;
|
2021-03-24 16:01:34 +08:00
|
|
|
|
using System.Linq;
|
2021-03-19 17:02:57 +08:00
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.AspNetCore.Cors;
|
|
|
|
|
using LeanCloud.Storage;
|
2021-03-24 16:01:34 +08:00
|
|
|
|
using LeanCloud.Storage.Internal.Codec;
|
2021-03-19 17:02:57 +08:00
|
|
|
|
|
|
|
|
|
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)) {
|
2021-03-24 16:01:34 +08:00
|
|
|
|
LCEngine.InitRequestContext(Request);
|
|
|
|
|
|
|
|
|
|
object[] ps = ParseParameters(mi, body);
|
|
|
|
|
object result = await LCEngine.Invoke(mi, ps.ToArray());
|
|
|
|
|
|
2021-03-19 17:02:57 +08:00
|
|
|
|
if (result != null) {
|
|
|
|
|
return new Dictionary<string, object> {
|
2021-03-22 17:06:12 +08:00
|
|
|
|
{ "result", result }
|
|
|
|
|
};
|
2021-03-19 17:02:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-24 16:01:34 +08:00
|
|
|
|
return body;
|
2021-03-19 17:02:57 +08:00
|
|
|
|
} 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)) {
|
2021-03-24 16:01:34 +08:00
|
|
|
|
LCEngine.InitRequestContext(Request);
|
|
|
|
|
|
|
|
|
|
object[] ps = ParseParameters(mi, body);
|
|
|
|
|
object result = await LCEngine.Invoke(mi, ps);
|
|
|
|
|
|
2021-03-19 17:02:57 +08:00
|
|
|
|
if (result != null) {
|
|
|
|
|
return new Dictionary<string, object> {
|
2021-03-24 16:01:34 +08:00
|
|
|
|
{ "result", LCCloud.Encode(result) }
|
|
|
|
|
};
|
2021-03-19 17:02:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-24 16:01:34 +08:00
|
|
|
|
return body;
|
2021-03-19 17:02:57 +08:00
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return StatusCode(500, e.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-24 16:01:34 +08:00
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
2021-03-19 17:02:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|