|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using SqlSugar;
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Linq.Expressions;
|
|
|
|
using System.Reflection;
|
|
|
|
using System.Text;
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Globalization;
|
|
|
|
using System.Data;
|
|
|
|
|
|
|
|
namespace ReZero.SuperAPI
|
|
|
|
{
|
|
|
|
public class MethodGeneratorAPI : IDataService
|
|
|
|
{
|
|
|
|
private ISqlSugarClient db;
|
|
|
|
public MethodGeneratorAPI()
|
|
|
|
{
|
|
|
|
db = App.Db;
|
|
|
|
}
|
|
|
|
public async Task<object> ExecuteAction(DataModel dataModel)
|
|
|
|
{
|
|
|
|
if (dataModel.MyMethodInfo == null) return null;
|
|
|
|
|
|
|
|
var classType = Type.GetType(dataModel.MyMethodInfo?.MethodClassFullName);
|
|
|
|
classType = GetTypeByAttribute(dataModel, classType);
|
|
|
|
var methodInfo = classType.GetMyMethod(dataModel?.MyMethodInfo?.MethodName, dataModel!.MyMethodInfo!.MethodArgsCount);
|
|
|
|
var classObj = ReZero.DependencyInjection.ActivatorHelper.CreateInstance(classType!, nonPublic: true, (ServiceProvider)dataModel.ServiceProvider!);
|
|
|
|
object[] parameters = new object[methodInfo.GetParameters().Length];
|
|
|
|
var argsTypes = dataModel.MyMethodInfo.ArgsTypes;
|
|
|
|
parameters = GetParameters(dataModel, methodInfo, parameters, argsTypes);
|
|
|
|
var unitType = methodInfo.GetCustomAttributes().FirstOrDefault(it => it.GetType().GetInterfaces().Any(s => s == typeof(IUnitOfWork)));
|
|
|
|
if (unitType != null)
|
|
|
|
{
|
|
|
|
var unitObj =(IUnitOfWork)ReZero.DependencyInjection.ActivatorHelper.CreateInstance(unitType!.GetType(), nonPublic: true, (ServiceProvider)dataModel.ServiceProvider!);
|
|
|
|
unitObj.db = ((ServiceProvider)dataModel.ServiceProvider!).GetRequiredService<ISqlSugarClient>();
|
|
|
|
try
|
|
|
|
{
|
|
|
|
unitObj.BeginTran();
|
|
|
|
object result = new object();
|
|
|
|
result = await ExecuteMethodAsync(methodInfo, classObj, parameters);
|
|
|
|
unitObj.CommitTran();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
catch (Exception)
|
|
|
|
{
|
|
|
|
unitObj.RollbackTran();
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
object result = await ExecuteMethodAsync(methodInfo, classObj, parameters);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private object[] GetParameters(DataModel dataModel, MethodInfo methodInfo, object[] parameters, Type[]? argsTypes)
|
|
|
|
{
|
|
|
|
// 先检查method的参数类型
|
|
|
|
var methodParams = methodInfo.GetParameters();
|
|
|
|
|
|
|
|
// 使用新的参数绑定方式:直接根据方法参数类型进行JSON绑定
|
|
|
|
if (!string.IsNullOrEmpty(dataModel.RawJsonData))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
bool bindingSuccess = DirectJsonParameterBinding(dataModel, methodInfo, parameters);
|
|
|
|
if (bindingSuccess)
|
|
|
|
{
|
|
|
|
return parameters;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"直接绑定失败: {ex.Message},回退到原有绑定方式");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果直接绑定失败,回退到现有逻辑
|
|
|
|
// 先尝试判断是否是JToken/JObject参数
|
|
|
|
if (methodParams.Length == 1 &&
|
|
|
|
(typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(methodParams[0].ParameterType)))
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"检测到JToken类型参数: {methodParams[0].ParameterType.Name}");
|
|
|
|
// 直接通过参数类型判断
|
|
|
|
FillJObjectDirectly(dataModel, methodParams[0].ParameterType, parameters);
|
|
|
|
}
|
|
|
|
else if (IsJObject(dataModel, parameters))
|
|
|
|
{
|
|
|
|
// 通过参数定义判断
|
|
|
|
FillJObjectParameters(dataModel, methodInfo, parameters, argsTypes);
|
|
|
|
}
|
|
|
|
else if (IsSingleModel(dataModel))
|
|
|
|
{
|
|
|
|
parameters = FillSingleModelParameters(dataModel, methodInfo);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FillDefaultParameters(dataModel, methodInfo, parameters, argsTypes);
|
|
|
|
}
|
|
|
|
|
|
|
|
return parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static async Task<object> ExecuteMethodAsync(MethodInfo methodInfo, object classObj, object[] parameters)
|
|
|
|
{
|
|
|
|
var result = methodInfo.Invoke(classObj, parameters);
|
|
|
|
if (result is Task)
|
|
|
|
{
|
|
|
|
result = await GetTask((Task)result);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = await Task.FromResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static object[] FillSingleModelParameters(DataModel dataModel, MethodInfo methodInfo)
|
|
|
|
{
|
|
|
|
object[] parameters;
|
|
|
|
var type = methodInfo.GetParameters().First().ParameterType;
|
|
|
|
var parameterOjb = Activator.CreateInstance(type, nonPublic: true);
|
|
|
|
foreach (var item in type!.GetProperties())
|
|
|
|
{
|
|
|
|
// 确保属性有set方法
|
|
|
|
if (!item.CanWrite)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// 获取对应的参数数据
|
|
|
|
var propertyParam = dataModel.DefaultParameters.FirstOrDefault(it => it.Name == item.Name);
|
|
|
|
if (propertyParam == null)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
propertyParam.Value = ConvetEmptyValue(item.PropertyType, propertyParam.Value);
|
|
|
|
|
|
|
|
// 特殊处理JToken及其子类型
|
|
|
|
if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(item.PropertyType))
|
|
|
|
{
|
|
|
|
if (item.PropertyType == typeof(Newtonsoft.Json.Linq.JObject))
|
|
|
|
{
|
|
|
|
string jsonStr = propertyParam.Value?.ToString() ?? "{}";
|
|
|
|
if (jsonStr.Trim() == "null") jsonStr = "{}";
|
|
|
|
try
|
|
|
|
{
|
|
|
|
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JObject.Parse(jsonStr));
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
item.SetValue(parameterOjb, new Newtonsoft.Json.Linq.JObject());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (item.PropertyType == typeof(Newtonsoft.Json.Linq.JArray))
|
|
|
|
{
|
|
|
|
string jsonStr = propertyParam.Value?.ToString() ?? "[]";
|
|
|
|
if (jsonStr.Trim() == "null") jsonStr = "[]";
|
|
|
|
try
|
|
|
|
{
|
|
|
|
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JArray.Parse(jsonStr));
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
item.SetValue(parameterOjb, new Newtonsoft.Json.Linq.JArray());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (item.PropertyType == typeof(Newtonsoft.Json.Linq.JToken))
|
|
|
|
{
|
|
|
|
string jsonStr = propertyParam.Value?.ToString() ?? "null";
|
|
|
|
try
|
|
|
|
{
|
|
|
|
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JToken.Parse(jsonStr));
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
item.SetValue(parameterOjb, Newtonsoft.Json.Linq.JValue.CreateNull());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (IsJson(item, propertyParam))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var value = JsonConvert.DeserializeObject(propertyParam.Value + "", item.PropertyType);
|
|
|
|
item.SetValue(parameterOjb, value);
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
// 如果JSON反序列化失败,尝试使用默认值
|
|
|
|
if (item.PropertyType.IsValueType)
|
|
|
|
item.SetValue(parameterOjb, Activator.CreateInstance(item.PropertyType));
|
|
|
|
else
|
|
|
|
item.SetValue(parameterOjb, null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 尝试使用类型转换设置值
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var convertedValue = UtilMethods.ChangeType2(propertyParam.Value, item.PropertyType);
|
|
|
|
item.SetValue(parameterOjb, convertedValue);
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
// 如果类型转换失败,使用默认值
|
|
|
|
if (item.PropertyType.IsValueType)
|
|
|
|
item.SetValue(parameterOjb, Activator.CreateInstance(item.PropertyType));
|
|
|
|
else
|
|
|
|
item.SetValue(parameterOjb, null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception)
|
|
|
|
{
|
|
|
|
// 如果设置属性值失败,继续处理下一个属性
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parameters = new object[] { parameterOjb };
|
|
|
|
return parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static bool IsJson(PropertyInfo item, DataModelDefaultParameter p)
|
|
|
|
{
|
|
|
|
if (item.PropertyType?.FullName?.StartsWith("System.Collections.Generic.List")==true)
|
|
|
|
{
|
|
|
|
var value2 = p.Value?.ToString()?.Trim();
|
|
|
|
return value2?.StartsWith("[") == true && value2?.EndsWith("]") == true;
|
|
|
|
}
|
|
|
|
if (item.PropertyType?.FullName?.StartsWith("System.")==true)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
var value = p.Value?.ToString()?.Trim();
|
|
|
|
return value?.StartsWith("{") == true && value?.EndsWith("}") == true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static bool IsSingleModel(DataModel dataModel)
|
|
|
|
{
|
|
|
|
return dataModel.MyMethodInfo?.ArgsTypes?.Any(it => typeof(SingleModel) == it) == true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static Type? GetTypeByAttribute(DataModel dataModel, Type? classType)
|
|
|
|
{
|
|
|
|
if (classType == null)
|
|
|
|
{
|
|
|
|
var ass = SuperAPIModule._apiOptions?.DependencyInjectionOptions?.Assemblies;
|
|
|
|
if (ass?.Any() == true)
|
|
|
|
{
|
|
|
|
classType = ass.Select(it => it.GetType(dataModel.MyMethodInfo?.MethodClassFullName)).Where(it => it != null).FirstOrDefault();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return classType;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void FillJObjectParameters(DataModel dataModel, MethodInfo methodInfo, object[] parameters, Type[]? argsTypes)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 检查DefaultParameters是否有效
|
|
|
|
if (dataModel?.DefaultParameters == null || !dataModel.DefaultParameters.Any())
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine("DefaultParameters为空或null");
|
|
|
|
return; // 无法继续
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取原始JSON数据
|
|
|
|
var rawJson = dataModel.RawJsonData;
|
|
|
|
if (string.IsNullOrEmpty(rawJson))
|
|
|
|
{
|
|
|
|
// 如果RawJsonData为空,尝试从第一个参数获取值(向后兼容)
|
|
|
|
var firstParam = dataModel.DefaultParameters.First();
|
|
|
|
rawJson = firstParam.Value?.ToString() ?? "";
|
|
|
|
}
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"使用JSON数据: {rawJson}");
|
|
|
|
|
|
|
|
// 如果JSON为空,无法继续
|
|
|
|
if (string.IsNullOrEmpty(rawJson))
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine("JSON数据为空,无法处理参数");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 解析JSON
|
|
|
|
JObject jsonObj = JObject.Parse(rawJson);
|
|
|
|
|
|
|
|
// 获取方法参数信息
|
|
|
|
var methodParams = methodInfo.GetParameters();
|
|
|
|
if (methodParams.Length == 1)
|
|
|
|
{
|
|
|
|
// 单参数方法的处理
|
|
|
|
var paramInfo = methodParams[0];
|
|
|
|
var paramName = paramInfo.Name;
|
|
|
|
var paramType = paramInfo.ParameterType;
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"参数名: {paramName}, 类型: {paramType.Name}");
|
|
|
|
|
|
|
|
// 特殊处理:如果参数类型为JObject或JToken,直接使用整个JSON对象
|
|
|
|
if (typeof(JToken).IsAssignableFrom(paramType))
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"检测到JToken类型参数,直接使用整个JSON对象");
|
|
|
|
if (paramType == typeof(JObject))
|
|
|
|
{
|
|
|
|
parameters[0] = jsonObj;
|
|
|
|
System.Diagnostics.Debug.WriteLine("成功绑定JObject参数");
|
|
|
|
}
|
|
|
|
else if (paramType == typeof(JToken))
|
|
|
|
{
|
|
|
|
parameters[0] = (JToken)jsonObj;
|
|
|
|
System.Diagnostics.Debug.WriteLine("成功绑定JToken参数");
|
|
|
|
}
|
|
|
|
else if (paramType == typeof(JArray))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
parameters[0] = JArray.Parse(rawJson);
|
|
|
|
System.Diagnostics.Debug.WriteLine("成功绑定JArray参数");
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine("JSON不是有效的数组格式,无法绑定JArray参数");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return; // 处理完成,直接返回
|
|
|
|
}
|
|
|
|
|
|
|
|
// 检查JSON中是否存在与参数同名的属性
|
|
|
|
if (jsonObj.ContainsKey(paramName))
|
|
|
|
{
|
|
|
|
// JSON对象中有与参数同名的属性,使用该属性值
|
|
|
|
System.Diagnostics.Debug.WriteLine($"找到与参数同名的JSON属性: {paramName}");
|
|
|
|
JToken propValue = jsonObj[paramName];
|
|
|
|
|
|
|
|
// 转换为参数类型
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 特殊处理List<T>类型参数
|
|
|
|
if (propValue.Type == JTokenType.Array &&
|
|
|
|
paramType.IsGenericType &&
|
|
|
|
paramType.GetGenericTypeDefinition() == typeof(List<>))
|
|
|
|
{
|
|
|
|
// 获取List的泛型参数类型
|
|
|
|
Type itemType = paramType.GetGenericArguments()[0];
|
|
|
|
System.Diagnostics.Debug.WriteLine($"处理List<{itemType.Name}>类型参数");
|
|
|
|
|
|
|
|
// 获取JSON数组字符串
|
|
|
|
string arrayJson = propValue.ToString();
|
|
|
|
|
|
|
|
// 使用指定的设置反序列化
|
|
|
|
var settings = new JsonSerializerSettings
|
|
|
|
{
|
|
|
|
TypeNameHandling = TypeNameHandling.Auto
|
|
|
|
};
|
|
|
|
parameters[0] = JsonConvert.DeserializeObject(arrayJson, paramType, settings);
|
|
|
|
|
|
|
|
// 如果反序列化结果为null,则创建空列表
|
|
|
|
if (parameters[0] == null)
|
|
|
|
{
|
|
|
|
var listType = typeof(List<>).MakeGenericType(itemType);
|
|
|
|
parameters[0] = Activator.CreateInstance(listType);
|
|
|
|
}
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"成功将数组属性 {paramName} 转换为List类型");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 一般类型转换
|
|
|
|
parameters[0] = propValue.ToObject(paramType);
|
|
|
|
System.Diagnostics.Debug.WriteLine($"成功将属性 {paramName} 转换为 {paramType.Name} 类型");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception propEx)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"属性 {paramName} 转换为 {paramType.Name} 失败: {propEx.Message}");
|
|
|
|
// 如果属性转换失败,尝试使用整个JSON对象
|
|
|
|
try
|
|
|
|
{
|
|
|
|
parameters[0] = JsonConvert.DeserializeObject(rawJson, paramType);
|
|
|
|
System.Diagnostics.Debug.WriteLine($"回退到将整个JSON转换为 {paramType.Name}");
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"JSON转换失败: {ex.Message}");
|
|
|
|
// 参数保持默认值
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// JSON中没有与参数同名的属性,尝试直接转换整个JSON
|
|
|
|
System.Diagnostics.Debug.WriteLine($"未找到与参数 {paramName} 同名的JSON属性,尝试转换整个JSON");
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 尝试直接将JSON反序列化为参数类型
|
|
|
|
parameters[0] = JsonConvert.DeserializeObject(rawJson, paramType);
|
|
|
|
System.Diagnostics.Debug.WriteLine($"成功将JSON反序列化为: {paramType.Name}");
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"JSON反序列化失败: {ex.Message}");
|
|
|
|
System.Diagnostics.Debug.WriteLine($"无法将JSON转换为类型 {paramType.Name}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (methodParams.Length > 1)
|
|
|
|
{
|
|
|
|
// 多参数方法的处理
|
|
|
|
System.Diagnostics.Debug.WriteLine($"多参数方法,参数数量: {methodParams.Length}");
|
|
|
|
|
|
|
|
for (int i = 0; i < methodParams.Length; i++)
|
|
|
|
{
|
|
|
|
var paramInfo = methodParams[i];
|
|
|
|
var paramName = paramInfo.Name;
|
|
|
|
var paramType = paramInfo.ParameterType;
|
|
|
|
|
|
|
|
// 查找JSON中是否有对应属性
|
|
|
|
if (jsonObj.ContainsKey(paramName))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
JToken propValue = jsonObj[paramName];
|
|
|
|
parameters[i] = propValue.ToObject(paramType);
|
|
|
|
System.Diagnostics.Debug.WriteLine($"已绑定参数 {paramName} 为JSON属性值");
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"参数 {paramName} 绑定失败: {ex.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"FillJObjectParameters处理JSON时出错: {ex.Message}");
|
|
|
|
|
|
|
|
// 回退到原始方法
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var paramInfo = methodInfo.GetParameters().First();
|
|
|
|
var paramType = paramInfo.ParameterType;
|
|
|
|
|
|
|
|
// 对于JObject/JToken类型,尝试直接解析
|
|
|
|
if (typeof(JToken).IsAssignableFrom(paramType))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (paramType == typeof(JObject))
|
|
|
|
{
|
|
|
|
parameters[0] = JObject.Parse(rawJson);
|
|
|
|
System.Diagnostics.Debug.WriteLine("回退处理:成功解析为JObject");
|
|
|
|
}
|
|
|
|
else if (paramType == typeof(JToken))
|
|
|
|
{
|
|
|
|
parameters[0] = JToken.Parse(rawJson);
|
|
|
|
System.Diagnostics.Debug.WriteLine("回退处理:成功解析为JToken");
|
|
|
|
}
|
|
|
|
else if (paramType == typeof(JArray))
|
|
|
|
{
|
|
|
|
parameters[0] = JArray.Parse(rawJson);
|
|
|
|
System.Diagnostics.Debug.WriteLine("回退处理:成功解析为JArray");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception jEx)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"回退处理JToken解析失败: {jEx.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parameters[0] = JsonConvert.DeserializeObject(rawJson, paramType);
|
|
|
|
System.Diagnostics.Debug.WriteLine("回退处理:使用JsonConvert反序列化");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception fallbackEx)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"回退处理失败: {fallbackEx.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"FillJObjectParameters异常: {ex.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static bool IsJObject(DataModel dataModel, object[] parameters)
|
|
|
|
{
|
|
|
|
if (parameters.Length != 1 || dataModel.DefaultParameters.Count == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
var firstParam = dataModel.DefaultParameters.First();
|
|
|
|
|
|
|
|
// 检查是否已标记为JObject类型
|
|
|
|
bool isJObjectType = firstParam.ValueType == nameof(JObject) ||
|
|
|
|
firstParam.ValueType == nameof(JToken) ||
|
|
|
|
firstParam.ValueType == "JTokenType" ||
|
|
|
|
firstParam.ValueType == "Json" ||
|
|
|
|
firstParam.ValueType?.Contains("JObject") == true ||
|
|
|
|
firstParam.ValueType?.Contains("JToken") == true;
|
|
|
|
|
|
|
|
// 检查是否为单个参数
|
|
|
|
bool isSingleParam = dataModel.DefaultParameters.Count == 1;
|
|
|
|
|
|
|
|
// 检查JSON字符串
|
|
|
|
bool isJsonString = firstParam.Value != null && IsJsonString(firstParam.Value.ToString());
|
|
|
|
|
|
|
|
return isSingleParam && (isJObjectType || isJsonString);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static bool IsJsonString(string value)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(value))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
value = value.Trim();
|
|
|
|
return (value.StartsWith("{") && value.EndsWith("}")) ||
|
|
|
|
(value.StartsWith("[") && value.EndsWith("]"));
|
|
|
|
}
|
|
|
|
|
|
|
|
private static int FillDefaultParameters(DataModel dataModel, MethodInfo methodInfo, object[] parameters, Type[]? argsTypes)
|
|
|
|
{
|
|
|
|
var index = 0;
|
|
|
|
|
|
|
|
// 特殊处理GetToken方法,确保参数正确传递
|
|
|
|
if (methodInfo.Name == "GetToken" && dataModel.DefaultParameters?.Count == 2 && methodInfo.GetParameters().Length == 2)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine("检测到GetToken方法,尝试特殊处理登录参数");
|
|
|
|
|
|
|
|
// 获取用户名和密码参数
|
|
|
|
var userNameParam = dataModel.DefaultParameters.FirstOrDefault(it => it.Name?.EqualsCase("UserName") == true);
|
|
|
|
var passwordParam = dataModel.DefaultParameters.FirstOrDefault(it => it.Name?.EqualsCase("Password") == true);
|
|
|
|
|
|
|
|
// 检查用户名参数
|
|
|
|
if (userNameParam?.Value == null)
|
|
|
|
{
|
|
|
|
// 如果找不到用户名参数值,尝试从原始JSON中提取
|
|
|
|
if (dataModel.DefaultParameters.Any(p => p.Value?.ToString()?.Contains("userName") == true || p.Value?.ToString()?.Contains("UserName") == true))
|
|
|
|
{
|
|
|
|
var jsonStr = dataModel.DefaultParameters.First(p => p.Value?.ToString()?.Contains("userName") == true || p.Value?.ToString()?.Contains("UserName") == true).Value?.ToString();
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonStr ?? "{}");
|
|
|
|
if (jsonObj != null)
|
|
|
|
{
|
|
|
|
if (jsonObj.ContainsKey("userName"))
|
|
|
|
userNameParam.Value = jsonObj["userName"];
|
|
|
|
else if (jsonObj.ContainsKey("UserName"))
|
|
|
|
userNameParam.Value = jsonObj["UserName"];
|
|
|
|
|
|
|
|
if (jsonObj.ContainsKey("password"))
|
|
|
|
passwordParam.Value = jsonObj["password"];
|
|
|
|
else if (jsonObj.ContainsKey("Password"))
|
|
|
|
passwordParam.Value = jsonObj["Password"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"解析登录JSON参数失败: {ex.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 赋值参数
|
|
|
|
parameters[0] = userNameParam?.Value?.ToString() ?? "";
|
|
|
|
parameters[1] = passwordParam?.Value?.ToString() ?? "";
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"登录参数: UserName={parameters[0]}, Password={(parameters[1]?.ToString()?.Length > 0 ? "********" : "null")}");
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 常规参数处理
|
|
|
|
methodInfo.GetParameters().ToList<System.Reflection.ParameterInfo>().ForEach((p) =>
|
|
|
|
{
|
|
|
|
object? value = dataModel?.DefaultParameters?.FirstOrDefault(it => it.Name!.EqualsCase(p.Name)).Value;
|
|
|
|
if (argsTypes?.Length - 1 >= index)
|
|
|
|
{
|
|
|
|
var type = argsTypes![index];
|
|
|
|
if (IsObject(value, type))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var valueStr = value?.ToString();
|
|
|
|
if (!string.IsNullOrEmpty(valueStr))
|
|
|
|
{
|
|
|
|
value = JsonConvert.DeserializeObject(valueStr, type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (JsonException ex)
|
|
|
|
{
|
|
|
|
throw new Exception(TextHandler.GetCommonText(p.Name + "JSON解析错误: " + ex.Message,
|
|
|
|
p.Name + " JSON parsing error: " + ex.Message));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
value = ConvetEmptyValue(p.ParameterType, value);
|
|
|
|
value = UtilMethods.ChangeType2(value, p.ParameterType);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
throw new Exception(TextHandler.GetCommonText(p.Name + "参数类型不匹配 " + value + ", 错误: " + ex.Message,
|
|
|
|
p.Name + " Parameter type does not match " + value + ", Error: " + ex.Message));
|
|
|
|
}
|
|
|
|
parameters[p.Position] = value!;
|
|
|
|
index++;
|
|
|
|
});
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static object? ConvetEmptyValue(Type type, object? value)
|
|
|
|
{
|
|
|
|
if (value?.Equals("") == true && type != typeof(string))
|
|
|
|
{
|
|
|
|
value = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 处理JToken及其子类型
|
|
|
|
if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(type))
|
|
|
|
{
|
|
|
|
var jTokenValue = value?.ToString()?.Trim();
|
|
|
|
if (string.IsNullOrEmpty(jTokenValue))
|
|
|
|
{
|
|
|
|
// 为各种JToken类型提供默认值
|
|
|
|
if (type == typeof(Newtonsoft.Json.Linq.JObject))
|
|
|
|
return "{}";
|
|
|
|
else if (type == typeof(Newtonsoft.Json.Linq.JArray))
|
|
|
|
return "[]";
|
|
|
|
else
|
|
|
|
return "null";
|
|
|
|
}
|
|
|
|
return jTokenValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 处理JSON数组或对象
|
|
|
|
var strValue = value?.ToString()?.Trim();
|
|
|
|
if (strValue != null)
|
|
|
|
{
|
|
|
|
if ((type.IsArray || type.FullName.StartsWith("System.Collections.Generic.List")) &&
|
|
|
|
strValue.StartsWith("[") && strValue.EndsWith("]"))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return JsonConvert.DeserializeObject(strValue, type);
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
// 保持原始值
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!type.FullName.StartsWith("System.") &&
|
|
|
|
strValue.StartsWith("{") && strValue.EndsWith("}"))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return JsonConvert.DeserializeObject(strValue, type);
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
// 保持原始值
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
private static async Task<object> GetTask(Task task)
|
|
|
|
{
|
|
|
|
await task.ConfigureAwait(false); // 等待任务完成
|
|
|
|
var resultProperty = task.GetType().GetProperty("Result");
|
|
|
|
var result = resultProperty.GetValue(task);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
private static bool IsObject(object? value, Type type)
|
|
|
|
{
|
|
|
|
if ((type.IsArray || type.FullName.StartsWith("System.Collections.Generic.List")) && value != null)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 检查值是否为JSON数组字符串
|
|
|
|
var valueStr = value?.ToString()?.Trim();
|
|
|
|
if (valueStr != null && valueStr.StartsWith("[") && valueStr.EndsWith("]"))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 直接填充JObject参数,简化处理
|
|
|
|
private void FillJObjectDirectly(DataModel dataModel, Type parameterType, object[] parameters)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine("直接填充JObject参数");
|
|
|
|
if (dataModel?.DefaultParameters == null || !dataModel.DefaultParameters.Any())
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine("直接填充JObject - 参数列表为空");
|
|
|
|
parameters[0] = CreateDefaultJToken(parameterType);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var jsonData = dataModel.DefaultParameters.First().Value?.ToString();
|
|
|
|
if (string.IsNullOrEmpty(jsonData))
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine("直接填充JObject - 参数值为空");
|
|
|
|
parameters[0] = CreateDefaultJToken(parameterType);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"直接填充JObject - JSON数据: {jsonData}");
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 检查是否需要处理嵌套的数据结构
|
|
|
|
if (jsonData.Contains("\"methodName\"") && jsonData.Contains("\"data\"") &&
|
|
|
|
parameterType == typeof(Newtonsoft.Json.Linq.JObject))
|
|
|
|
{
|
|
|
|
var jobj = Newtonsoft.Json.Linq.JObject.Parse(jsonData);
|
|
|
|
// ExecuteTransaction方法直接需要整个请求对象,无需处理
|
|
|
|
parameters[0] = jobj;
|
|
|
|
}
|
|
|
|
else if (parameterType == typeof(Newtonsoft.Json.Linq.JObject))
|
|
|
|
{
|
|
|
|
parameters[0] = Newtonsoft.Json.Linq.JObject.Parse(jsonData);
|
|
|
|
}
|
|
|
|
else if (parameterType == typeof(Newtonsoft.Json.Linq.JArray))
|
|
|
|
{
|
|
|
|
parameters[0] = Newtonsoft.Json.Linq.JArray.Parse(jsonData);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parameters[0] = Newtonsoft.Json.Linq.JToken.Parse(jsonData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"直接填充JObject - 解析异常: {ex.Message}");
|
|
|
|
parameters[0] = CreateDefaultJToken(parameterType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"直接填充JObject - 总异常: {ex.Message}");
|
|
|
|
parameters[0] = CreateDefaultJToken(parameterType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 创建默认的JToken对象
|
|
|
|
private static Newtonsoft.Json.Linq.JToken CreateDefaultJToken(Type parameterType)
|
|
|
|
{
|
|
|
|
if (parameterType == typeof(Newtonsoft.Json.Linq.JObject))
|
|
|
|
return new Newtonsoft.Json.Linq.JObject();
|
|
|
|
else if (parameterType == typeof(Newtonsoft.Json.Linq.JArray))
|
|
|
|
return new Newtonsoft.Json.Linq.JArray();
|
|
|
|
else
|
|
|
|
return Newtonsoft.Json.Linq.JValue.CreateNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 直接根据方法参数信息进行JSON绑定
|
|
|
|
private bool DirectJsonParameterBinding(DataModel dataModel, MethodInfo methodInfo, object[] parameters)
|
|
|
|
{
|
|
|
|
var rawJson = dataModel.RawJsonData;
|
|
|
|
if (string.IsNullOrEmpty(rawJson))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"直接根据方法参数进行JSON绑定,JSON: {rawJson}");
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 解析JSON
|
|
|
|
JObject jsonObj = JObject.Parse(rawJson);
|
|
|
|
var methodParams = methodInfo.GetParameters();
|
|
|
|
|
|
|
|
// 检查参数数量
|
|
|
|
if (methodParams.Length == 0)
|
|
|
|
{
|
|
|
|
return false; // 没有参数需要绑定
|
|
|
|
}
|
|
|
|
|
|
|
|
// 单参数情况优先处理
|
|
|
|
if (methodParams.Length == 1)
|
|
|
|
{
|
|
|
|
var paramInfo = methodParams[0];
|
|
|
|
var paramName = paramInfo.Name;
|
|
|
|
var paramType = paramInfo.ParameterType;
|
|
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"单参数处理: 名称={paramName}, 类型={paramType.FullName}");
|
|
|
|
|
|
|
|
// 处理JToken及其子类型
|
|
|
|
if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(paramType))
|
|
|
|
{
|
|
|
|
parameters[0] = paramType == typeof(Newtonsoft.Json.Linq.JObject)
|
|
|
|
? jsonObj
|
|
|
|
: (paramType == typeof(Newtonsoft.Json.Linq.JArray)
|
|
|
|
? JArray.Parse(rawJson)
|
|
|
|
: JToken.Parse(rawJson));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 检查是否有与参数同名的属性
|
|
|
|
if (jsonObj.ContainsKey(paramName))
|
|
|
|
{
|
|
|
|
JToken propValue = jsonObj[paramName];
|
|
|
|
|
|
|
|
// 特殊处理泛型List
|
|
|
|
if (propValue.Type == JTokenType.Array &&
|
|
|
|
paramType.IsGenericType &&
|
|
|
|
paramType.GetGenericTypeDefinition() == typeof(List<>))
|
|
|
|
{
|
|
|
|
Type itemType = paramType.GetGenericArguments()[0];
|
|
|
|
System.Diagnostics.Debug.WriteLine($"泛型List处理: 项类型={itemType.FullName}");
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 使用TypeNameHandling.All可以帮助处理多态类型
|
|
|
|
var serializerSettings = new JsonSerializerSettings
|
|
|
|
{
|
|
|
|
TypeNameHandling = TypeNameHandling.Auto,
|
|
|
|
NullValueHandling = NullValueHandling.Ignore
|
|
|
|
};
|
|
|
|
|
|
|
|
string arrayJson = propValue.ToString();
|
|
|
|
var listObj = JsonConvert.DeserializeObject(arrayJson, paramType, serializerSettings);
|
|
|
|
|
|
|
|
// 如果反序列化结果为null,尝试手动创建列表
|
|
|
|
if (listObj == null)
|
|
|
|
{
|
|
|
|
var listType = typeof(List<>).MakeGenericType(itemType);
|
|
|
|
var list = Activator.CreateInstance(listType);
|
|
|
|
|
|
|
|
// 手动将每个JSON项转换为目标类型
|
|
|
|
JArray jArray = JArray.Parse(arrayJson);
|
|
|
|
var addMethod = listType.GetMethod("Add");
|
|
|
|
|
|
|
|
foreach (var item in jArray)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var objItem = item.ToObject(itemType, JsonSerializer.Create(serializerSettings));
|
|
|
|
addMethod.Invoke(list, new[] { objItem });
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"列表项转换失败: {ex.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
listObj = list;
|
|
|
|
}
|
|
|
|
|
|
|
|
parameters[0] = listObj;
|
|
|
|
System.Diagnostics.Debug.WriteLine($"成功绑定List参数: 元素数量={(listObj as System.Collections.IList)?.Count ?? 0}");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"List绑定异常: {ex.Message}");
|
|
|
|
|
|
|
|
// 出错时创建空列表而不是返回null
|
|
|
|
var listType = typeof(List<>).MakeGenericType(itemType);
|
|
|
|
parameters[0] = Activator.CreateInstance(listType);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 常规类型转换
|
|
|
|
try
|
|
|
|
{
|
|
|
|
parameters[0] = propValue.ToObject(paramType);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
// 转换失败,继续使用回退处理
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 尝试将整个JSON对象反序列化为参数类型
|
|
|
|
try
|
|
|
|
{
|
|
|
|
parameters[0] = JsonConvert.DeserializeObject(rawJson, paramType);
|
|
|
|
if (parameters[0] != null)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
// 转换失败,继续使用回退处理
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 多参数处理
|
|
|
|
bool anyParamBound = false;
|
|
|
|
|
|
|
|
for (int i = 0; i < methodParams.Length; i++)
|
|
|
|
{
|
|
|
|
var paramInfo = methodParams[i];
|
|
|
|
var paramName = paramInfo.Name;
|
|
|
|
var paramType = paramInfo.ParameterType;
|
|
|
|
|
|
|
|
if (jsonObj.ContainsKey(paramName))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
JToken propValue = jsonObj[paramName];
|
|
|
|
|
|
|
|
// 特殊处理泛型List
|
|
|
|
if (propValue.Type == JTokenType.Array &&
|
|
|
|
paramType.IsGenericType &&
|
|
|
|
paramType.GetGenericTypeDefinition() == typeof(List<>))
|
|
|
|
{
|
|
|
|
Type itemType = paramType.GetGenericArguments()[0];
|
|
|
|
|
|
|
|
var serializerSettings = new JsonSerializerSettings
|
|
|
|
{
|
|
|
|
TypeNameHandling = TypeNameHandling.Auto,
|
|
|
|
NullValueHandling = NullValueHandling.Ignore
|
|
|
|
};
|
|
|
|
|
|
|
|
string arrayJson = propValue.ToString();
|
|
|
|
var listObj = JsonConvert.DeserializeObject(arrayJson, paramType, serializerSettings);
|
|
|
|
|
|
|
|
if (listObj == null)
|
|
|
|
{
|
|
|
|
var listType = typeof(List<>).MakeGenericType(itemType);
|
|
|
|
listObj = Activator.CreateInstance(listType);
|
|
|
|
}
|
|
|
|
|
|
|
|
parameters[i] = listObj;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parameters[i] = propValue.ToObject(paramType);
|
|
|
|
}
|
|
|
|
|
|
|
|
anyParamBound = true;
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"多参数绑定失败: {paramName}, {ex.Message}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return anyParamBound;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debug.WriteLine($"直接绑定总异常: {ex.Message}");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|