From 2c537c8fafcaa58d3237befa1cb62704b78928e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E9=B9=8F?= Date: Fri, 16 May 2025 16:23:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=A5=E5=8F=A3=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParameterProvider/BindHttpParameters.cs | 191 ++++++++++++++++-- .../ParameterProvider/ValidateParameters.cs | 43 +++- .../DataService/1Entities/DataModel.cs | 4 + .../MethodGeneratorAPI/MethodGeneratorAPI.cs | 170 +++++++++------- 4 files changed, 310 insertions(+), 98 deletions(-) diff --git a/ReZero/SuperAPI/ApiProvider/ParameterProvider/BindHttpParameters.cs b/ReZero/SuperAPI/ApiProvider/ParameterProvider/BindHttpParameters.cs index bfa53a6..cad081c 100644 --- a/ReZero/SuperAPI/ApiProvider/ParameterProvider/BindHttpParameters.cs +++ b/ReZero/SuperAPI/ApiProvider/ParameterProvider/BindHttpParameters.cs @@ -96,7 +96,9 @@ namespace ReZero.SuperAPI { string rawJson = formDatas["_rawJson"].ToString(); System.Diagnostics.Debug.WriteLine($"使用_rawJson作为JObject参数: {rawJson}"); - data.Value = rawJson; + + // 将原始JSON保存到DataModel的RawJsonData属性中,而不是直接修改参数值 + dataModel.RawJsonData = rawJson; // 特殊处理登录接口:如果是token接口,则需要额外处理参数 if (interInfo.Url == "/api/rezero/token" && dataModel.DefaultParameters.Count == 2) @@ -138,6 +140,37 @@ namespace ReZero.SuperAPI } } + // 从JSON对象中提取字段值并绑定到各个参数 + try + { + if (!string.IsNullOrEmpty(rawJson)) + { + JObject jsonObj = JObject.Parse(rawJson); + + // 对所有参数尝试从JSON中获取值,包括第一个参数 + foreach (var param in dataModel.DefaultParameters) + { + if (param?.Name != null) + { + // 尝试直接获取属性(不区分大小写) + var prop = jsonObj.Properties().FirstOrDefault(p => + p.Name.Equals(param.Name, StringComparison.OrdinalIgnoreCase)); + + if (prop != null) + { + // 根据属性类型进行适当转换,不仅仅是转换为字符串 + param.Value = ConvertJTokenToTypedValue(prop.Value); + Console.WriteLine($"从JSON提取参数: {param.Name} = {param.Value}"); + } + } + } + } + } + catch (Exception ex) + { + Console.WriteLine($"处理JSON参数时出错: {ex.Message}"); + } + return; // 已找到JSON数据,提前返回 } @@ -149,8 +182,37 @@ namespace ReZero.SuperAPI var body = reader.ReadToEndAsync().Result; if (!string.IsNullOrEmpty(body)) { - data.Value = body; + // 将原始JSON保存到DataModel的RawJsonData属性中 + dataModel.RawJsonData = body; System.Diagnostics.Debug.WriteLine($"JObject参数值设置为: {body}"); + + // 提取JSON对象中的字段绑定到参数 + try + { + JObject jsonObj = JObject.Parse(body); + + // 对所有参数尝试从JSON中获取值,包括第一个参数 + foreach (var param in dataModel.DefaultParameters) + { + if (param?.Name != null) + { + // 尝试直接获取属性(不区分大小写) + var prop = jsonObj.Properties().FirstOrDefault(p => + p.Name.Equals(param.Name, StringComparison.OrdinalIgnoreCase)); + + if (prop != null) + { + // 根据属性类型进行适当转换 + param.Value = ConvertJTokenToTypedValue(prop.Value); + Console.WriteLine($"从JSON提取参数: {param.Name} = {param.Value}"); + } + } + } + } + catch (Exception ex) + { + Console.WriteLine($"处理JSON参数时出错: {ex.Message}"); + } } else if (formDatas.ContainsKey("methodName") && formDatas.ContainsKey("data")) { @@ -160,13 +222,31 @@ namespace ReZero.SuperAPI methodName = formDatas["methodName"], data = formDatas["data"] }; - data.Value = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj); - System.Diagnostics.Debug.WriteLine($"从formDatas构建JObject参数: {data.Value}"); + var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj); + dataModel.RawJsonData = jsonString; + System.Diagnostics.Debug.WriteLine($"从formDatas构建JObject参数: {jsonString}"); + + // 提取methodName和data字段到相应参数 + if (dataModel.DefaultParameters.Count > 0) + { + var methodNameParam = dataModel.DefaultParameters.FirstOrDefault(p => p.Name?.EqualsCase("methodName") == true); + if (methodNameParam != null) + { + methodNameParam.Value = formDatas["methodName"].ToString(); + } + + var dataParam = dataModel.DefaultParameters.FirstOrDefault(p => p.Name?.EqualsCase("data") == true); + if (dataParam != null) + { + dataParam.Value = formDatas["data"].ToString(); + } + } } else { - data.Value = Newtonsoft.Json.JsonConvert.SerializeObject(formDatas); - System.Diagnostics.Debug.WriteLine($"使用formDatas序列化作为JObject参数: {data.Value}"); + var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(formDatas); + dataModel.RawJsonData = jsonString; + System.Diagnostics.Debug.WriteLine($"使用formDatas序列化作为JObject参数: {jsonString}"); } } context.Request.Body.Position = 0; @@ -174,7 +254,7 @@ namespace ReZero.SuperAPI catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"处理JObject参数异常: {ex.Message}"); - data.Value = Newtonsoft.Json.JsonConvert.SerializeObject(formDatas); + dataModel.RawJsonData = Newtonsoft.Json.JsonConvert.SerializeObject(formDatas); } } } @@ -224,7 +304,40 @@ namespace ReZero.SuperAPI private void UpdateWhereItemValue(HttpContext context, Dictionary formDatas, DataModelDefaultParameter item) { + // 添加调试日志 + if (item?.Name?.Equals("Name", StringComparison.OrdinalIgnoreCase) == true) + { + Console.WriteLine($"正在处理Name参数: 当前值={item.Value ?? "null"}"); + } + + // 先尝试从表单和查询字符串获取值 item.Value = GetParameterValueFromRequest(item, context, formDatas); + + // 如果没有获取到值且存在_rawJson,尝试从JSON中获取 + if ((item.Value == null || string.IsNullOrEmpty(item.Value.ToString())) && + formDatas.ContainsKey("_rawJson") && !string.IsNullOrEmpty(item.Name)) + { + try + { + string rawJson = formDatas["_rawJson"].ToString(); + var jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(rawJson); + + // 尝试直接找到匹配的属性(不区分大小写) + var prop = jsonObj?.Properties().FirstOrDefault(p => + p.Name.Equals(item.Name, StringComparison.OrdinalIgnoreCase)); + + if (prop != null) + { + item.Value = ConvertJTokenToTypedValue(prop.Value); + Console.WriteLine($"从JSON中提取参数: {item.Name} = {item.Value}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"从JSON提取参数时出错: {ex.Message}"); + } + } + if (IsDefaultValue(item)) { item.Value = item.DefaultValue; @@ -243,14 +356,14 @@ namespace ReZero.SuperAPI { item.Value = PubMethod.ConvertFromBase64(item.Value + ""); } - //if (!string.IsNullOrEmpty(item?.FieldName)) - //{ - // item.Name = item.FieldName; - //} + + // 再次记录处理后的值 + if (item?.Name?.Equals("Name", StringComparison.OrdinalIgnoreCase) == true) + { + Console.WriteLine($"Name参数处理后: 值={item.Value ?? "null"}"); + } } - - private static bool NoPageParameters(DataModelDefaultParameter it) { return it.Name != SuperAPIModule._apiOptions?.InterfaceOptions.PageNumberPropName && @@ -280,17 +393,25 @@ namespace ReZero.SuperAPI { return parameter.Value + ""; } + + // 先尝试从查询字符串中获取 string parameterValue = context.Request.Query[parameter.Name]; - var formData = formDatas.FirstOrDefault(it => it.Key.EqualsCase(parameter.Name ?? "")); - if (formData.Key == null) - { - // 尝试使用不区分大小写的方式查找 - formData = formDatas.FirstOrDefault(it => string.Equals(it.Key, parameter.Name, StringComparison.OrdinalIgnoreCase)); - } - if (formData.Key != null) + + // 如果查询字符串没有,再尝试从表单数据中获取 + if (string.IsNullOrEmpty(parameterValue)) { - parameterValue = formData.Value + ""; + var formData = formDatas.FirstOrDefault(it => it.Key.EqualsCase(parameter.Name ?? "")); + if (formData.Key == null) + { + // 尝试使用不区分大小写的方式查找 + formData = formDatas.FirstOrDefault(it => string.Equals(it.Key, parameter.Name, StringComparison.OrdinalIgnoreCase)); + } + if (formData.Key != null) + { + parameterValue = formData.Value + ""; + } } + parameter.Value = parameterValue; return parameterValue; } @@ -395,5 +516,33 @@ namespace ReZero.SuperAPI }; return context.Request.ContentType != null && contentTypes.Any(context.Request.ContentType.Contains); } + + // 根据JToken类型转换为适当的.NET类型 + private object ConvertJTokenToTypedValue(JToken token) + { + switch (token.Type) + { + case JTokenType.String: + return token.Value(); + case JTokenType.Integer: + return token.Value(); + case JTokenType.Float: + return token.Value(); + case JTokenType.Boolean: + return token.Value(); + case JTokenType.Date: + return token.Value(); + case JTokenType.Null: + return null; + case JTokenType.Object: + // 对于对象,返回序列化的JSON字符串而不是JObject本身 + return token.ToString(); + case JTokenType.Array: + // 对于数组,返回序列化的JSON字符串而不是JArray本身 + return token.ToString(); + default: + return token.ToString(); + } + } } } diff --git a/ReZero/SuperAPI/ApiProvider/ParameterProvider/ValidateParameters.cs b/ReZero/SuperAPI/ApiProvider/ParameterProvider/ValidateParameters.cs index 1fd8aed..4c2dc2b 100644 --- a/ReZero/SuperAPI/ApiProvider/ParameterProvider/ValidateParameters.cs +++ b/ReZero/SuperAPI/ApiProvider/ParameterProvider/ValidateParameters.cs @@ -14,10 +14,25 @@ namespace ReZero.SuperAPI public static async Task> CheckAsync(DataModel dataModel) { List errorLists = new List(); + + // 记录所有参数的状态,帮助调试 + Console.WriteLine("==== 开始参数验证 ===="); foreach (var item in dataModel.DefaultParameters ?? new List()) { + Console.WriteLine($"参数: {item.Name}, 值类型: {(item.Value?.GetType().Name ?? "null")}, 值: {(item.Value?.ToString() ?? "null")}"); + } + + foreach (var item in dataModel.DefaultParameters ?? new List()) + { + // 记录Name参数的检查 + if (item?.Name?.Equals("Name", StringComparison.OrdinalIgnoreCase) == true) + { + Console.WriteLine($"检查Name参数:Name={item.Name}, Value={(item.Value ?? "null")}, ValueType={(item.Value?.GetType().Name ?? "null")}"); + } + if (IsRequired(item)) { + Console.WriteLine($"参数 {item.Name} 验证失败: 必填但为空"); AddReuiredError(errorLists, item); } if (IsInsertUnique(dataModel, item)) @@ -28,6 +43,7 @@ namespace ReZero.SuperAPI { } } + Console.WriteLine("==== 参数验证结束 ===="); return errorLists; } @@ -58,10 +74,35 @@ namespace ReZero.SuperAPI { return item?.ParameterValidate?.IsUnique == true && dataModel.ActionType == ActionType.InsertObject; } + private static bool IsRequired(DataModelDefaultParameter item) { - return item?.ParameterValidate?.IsRequired == true && string.IsNullOrEmpty(item.Value + ""); + // 如果不是必填字段,直接返回false + if (item?.ParameterValidate?.IsRequired != true) + return false; + + // 如果值为null,则视为空 + if (item.Value == null) + return true; + + // 如果是字符串类型,检查是否为空字符串 + if (item.Value is string stringValue) + return string.IsNullOrWhiteSpace(stringValue); + + // 基本数值类型通常不视为空 + if (item.Value is int || item.Value is long || item.Value is decimal || + item.Value is double || item.Value is float || item.Value is bool) + return false; + + // JSON类型对象不视为空 + if (item.Value.GetType().FullName?.Contains("Newtonsoft.Json") == true) + return false; + + // 其他类型转换为字符串后判断 + string valueAsString = Convert.ToString(item.Value); + return string.IsNullOrWhiteSpace(valueAsString); } + private static async Task IsAnyValue(DataModelDefaultParameter? item, Type type, SqlSugarClient? db, EntityColumnInfo dbColumnInfo, EntityColumnInfo isDeleteIdColumn, DataModel dataModel) { var condition = new ConditionalModel() diff --git a/ReZero/SuperAPI/DataService/1Entities/DataModel.cs b/ReZero/SuperAPI/DataService/1Entities/DataModel.cs index ed800dd..98577fe 100644 --- a/ReZero/SuperAPI/DataService/1Entities/DataModel.cs +++ b/ReZero/SuperAPI/DataService/1Entities/DataModel.cs @@ -16,6 +16,10 @@ namespace ReZero.SuperAPI public string? Sql { get; set; } public SqlResultType? ResultType { get; set; } public string? TableColumns { get; set; } + /// + /// 存储原始的JSON数据,用于后续处理 + /// + public string? RawJsonData { get; set; } #endregion #region Paremters diff --git a/ReZero/SuperAPI/MethodGeneratorAPI/MethodGeneratorAPI.cs b/ReZero/SuperAPI/MethodGeneratorAPI/MethodGeneratorAPI.cs index b032391..badf7c6 100644 --- a/ReZero/SuperAPI/MethodGeneratorAPI/MethodGeneratorAPI.cs +++ b/ReZero/SuperAPI/MethodGeneratorAPI/MethodGeneratorAPI.cs @@ -5,13 +5,18 @@ 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 { - internal class MethodGeneratorAPI : IDataService + public class MethodGeneratorAPI : IDataService { private ISqlSugarClient db; public MethodGeneratorAPI() @@ -250,102 +255,66 @@ namespace ReZero.SuperAPI return; // 无法继续 } - // 获取第一个参数的值 - var param = dataModel.DefaultParameters.First(); - var value = param.Value?.ToString() ?? ""; - System.Diagnostics.Debug.WriteLine($"参数值: {value}"); - - var type = methodInfo.GetParameters().First().ParameterType; - System.Diagnostics.Debug.WriteLine($"参数类型: {type.FullName}"); - - // 检查值是否为JSON格式 - if (!string.IsNullOrWhiteSpace(value)) + // 获取第一个参数,但使用RawJsonData而不是参数值 + var rawJson = dataModel.RawJsonData; + if (string.IsNullOrEmpty(rawJson)) { - value = value.Trim(); - if (!((value.StartsWith("{") && value.EndsWith("}")) || - (value.StartsWith("[") && value.EndsWith("]")))) - { - System.Diagnostics.Debug.WriteLine("值不是有效的JSON格式"); - // 尝试将值包装为JSON格式 - value = $"{{\"_value\": {value}}}"; - System.Diagnostics.Debug.WriteLine($"转换为: {value}"); - } + // 如果RawJsonData为空,尝试从第一个参数获取值(向后兼容) + var firstParam = dataModel.DefaultParameters.First(); + rawJson = firstParam.Value?.ToString() ?? ""; } - // JToken及其派生类的特殊处理 - if (typeof(Newtonsoft.Json.Linq.JToken).IsAssignableFrom(type)) + System.Diagnostics.Debug.WriteLine($"使用JSON数据: {rawJson}"); + + var type = methodInfo.GetParameters().First().ParameterType; + + // 处理JSON数据 + if (!string.IsNullOrEmpty(rawJson)) { - System.Diagnostics.Debug.WriteLine("处理JToken类型"); try { - if (type == typeof(Newtonsoft.Json.Linq.JObject)) + // 检查原始JSON是否需要转义处理 + if (rawJson.Contains("\\\"")) { - if (string.IsNullOrEmpty(value) || value == "null") - { - value = "{}"; - } - - parameters[0] = Newtonsoft.Json.Linq.JObject.Parse(value); - System.Diagnostics.Debug.WriteLine("JObject解析成功"); + rawJson = rawJson.Replace("\\\"", "\""); } - else if (type == typeof(Newtonsoft.Json.Linq.JArray)) + + // 尝试反序列化为目标类型 + parameters[0] = Newtonsoft.Json.JsonConvert.DeserializeObject(rawJson, type); + System.Diagnostics.Debug.WriteLine($"成功将JSON反序列化为: {type.Name}"); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"JSON反序列化失败: {ex.Message}"); + + // 如果反序列化失败,尝试其他方式 + try { - if (string.IsNullOrEmpty(value) || value == "null") + if (type == typeof(Newtonsoft.Json.Linq.JObject)) { - value = "[]"; + parameters[0] = Newtonsoft.Json.Linq.JObject.Parse(rawJson); } - - parameters[0] = Newtonsoft.Json.Linq.JArray.Parse(value); - } - else // JToken或其他子类 - { - if (string.IsNullOrEmpty(value)) + else if (type == typeof(Newtonsoft.Json.Linq.JToken)) { - value = "null"; + parameters[0] = Newtonsoft.Json.Linq.JToken.Parse(rawJson); + } + else + { + // 最后尝试直接转换或使用默认值 + parameters[0] = Convert.ChangeType(rawJson, type); } - - parameters[0] = Newtonsoft.Json.Linq.JToken.Parse(value); - } - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"JSON解析错误: {ex.Message}"); - // 如果解析失败,创建一个空对象 - if (type == typeof(Newtonsoft.Json.Linq.JObject)) - { - parameters[0] = new Newtonsoft.Json.Linq.JObject(); - } - else if (type == typeof(Newtonsoft.Json.Linq.JArray)) - { - parameters[0] = new Newtonsoft.Json.Linq.JArray(); } - else + catch (Exception innerEx) { - parameters[0] = Newtonsoft.Json.Linq.JValue.CreateNull(); + System.Diagnostics.Debug.WriteLine($"参数转换失败: {innerEx.Message}"); + // 保持默认值 } } } - else if (!string.IsNullOrEmpty(value)) - { - System.Diagnostics.Debug.WriteLine("处理非JToken类型"); - // 非JToken类型的常规处理 - try - { - parameters[0] = JsonConvert.DeserializeObject(value, type)!; - if (parameters[0] is SaveInterfaceListModel saveInterfaceListModel) - { - saveInterfaceListModel.InterfaceCategoryId = Convert.ToInt64(Convert.ToDouble(saveInterfaceListModel.InterfaceCategoryId)) + ""; - } - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"非JToken反序列化错误: {ex.Message}"); - } - } } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine($"FillJObjectParameters总体异常: {ex.Message}"); + System.Diagnostics.Debug.WriteLine($"FillJObjectParameters异常: {ex.Message}"); } } @@ -386,6 +355,55 @@ namespace ReZero.SuperAPI 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>(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().ForEach((p) => { object? value = dataModel?.DefaultParameters?.FirstOrDefault(it => it.Name!.EqualsCase(p.Name)).Value;