using Microsoft.AspNetCore.Http; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace ReZero.SuperAPI { public partial class BindHttpParameters { internal void Bind(DataModel? dataModel, HttpContext context, string? path, bool isUrlParameters, ZeroInterfaceList interInfo) { var formDatas = GetFormDatas(context); BindPageParameters(dataModel, context, formDatas); BindDefaultParameters(dataModel, context, formDatas, interInfo); BindOrderByParameters(dataModel, context, formDatas); BindGroupByParameters(dataModel, context, formDatas); BindUrlParameters(isUrlParameters,path, dataModel!, interInfo); } private void BindUrlParameters(bool isUrlParameters, string? path, DataModel dataModel, ZeroInterfaceList interInfo) { if (isUrlParameters) { var parameterString = path!.Replace(interInfo.OriginalUrl!.ToLower(), string.Empty); var parameters= parameterString.Split('/').Where(it=>!string.IsNullOrWhiteSpace(it)).ToArray(); var index = 0; foreach (var item in dataModel.DefaultParameters??new List()) { item.Value= parameters[index]; index++; } } } private void BindGroupByParameters(DataModel? dataModel, HttpContext context, Dictionary formDatas) { if (dataModel?.GroupParemters != null) { var groupBys = formDatas.FirstOrDefault(it => it.Key.EqualsCase(nameof(DataModel.GroupParemters))); if (groupBys.Value != null) { dataModel!.GroupParemters = Newtonsoft.Json.JsonConvert.DeserializeObject>(groupBys.Value + ""); } } } private void BindOrderByParameters(DataModel? dataModel, HttpContext context, Dictionary formDatas) { if (dataModel?.OrderDynamicParemters != null) { //var data = dataModel?.DefaultParameters?.FirstOrDefault(it => it?.Name?.EqualsCase(nameof(DataModel.OrderByFixedParemters )) == true); //if (data != null) //{ var orderDatas = formDatas.FirstOrDefault(it => it.Key.EqualsCase(nameof(DataModel.OrderDynamicParemters))); if (orderDatas.Value != null) { dataModel!.OrderDynamicParemters = Newtonsoft.Json.JsonConvert.DeserializeObject>(orderDatas.Value + ""); } //} } } private void BindPageParameters(DataModel? dataModel, HttpContext context, Dictionary formDatas) { if (dataModel?.CommonPage != null) { var pageNumberPar = dataModel?.DefaultParameters?.FirstOrDefault(it => it?.Name?.EqualsCase(SuperAPIModule._apiOptions?.InterfaceOptions.PageNumberPropName) == true); if (pageNumberPar != null) { pageNumberPar.Value = GetParameterValueFromRequest(pageNumberPar, context, formDatas); dataModel!.CommonPage.PageNumber = Convert.ToInt32(pageNumberPar.Value ?? "1"); } var pageSizePar = dataModel?.DefaultParameters?.FirstOrDefault(it => it?.Name?.EqualsCase(SuperAPIModule._apiOptions?.InterfaceOptions.PageSizePropName) == true); if (pageSizePar != null) { pageSizePar.Value = GetParameterValueFromRequest(pageSizePar, context, formDatas); dataModel!.CommonPage.PageSize = Convert.ToInt32(pageSizePar.Value ?? "20"); } } } private void BindDefaultParameters(DataModel? dataModel, HttpContext context, Dictionary formDatas, ZeroInterfaceList interInfo) { if (IsJObjct(dataModel, formDatas)) { var data = dataModel?.DefaultParameters?.FirstOrDefault(); if (data != null) { System.Diagnostics.Debug.WriteLine("检测到JObject请求参数,开始处理"); try { // 先检查是否有_rawJson if (formDatas.ContainsKey("_rawJson")) { string rawJson = formDatas["_rawJson"].ToString(); System.Diagnostics.Debug.WriteLine($"使用_rawJson作为JObject参数: {rawJson}"); // 将原始JSON保存到DataModel的RawJsonData属性中,而不是直接修改参数值 dataModel.RawJsonData = rawJson; // 特殊处理登录接口:如果是token接口,则需要额外处理参数 if (interInfo.Url == "/api/rezero/token" && dataModel.DefaultParameters.Count == 2) { try { // 解析原始JSON以获取登录凭证 var loginParams = Newtonsoft.Json.JsonConvert.DeserializeObject>(rawJson); if (loginParams != null) { // 将用户名和密码分别赋值给对应参数 var userNameParam = dataModel.DefaultParameters.FirstOrDefault(p => p.Name?.EqualsCase("UserName") == true); var passwordParam = dataModel.DefaultParameters.FirstOrDefault(p => p.Name?.EqualsCase("Password") == true); if (userNameParam != null && loginParams.ContainsKey("UserName")) { userNameParam.Value = loginParams["UserName"]; } else if (userNameParam != null && loginParams.ContainsKey("userName")) { userNameParam.Value = loginParams["userName"]; } if (passwordParam != null && loginParams.ContainsKey("Password")) { passwordParam.Value = loginParams["Password"]; } else if (passwordParam != null && loginParams.ContainsKey("password")) { passwordParam.Value = loginParams["password"]; } System.Diagnostics.Debug.WriteLine($"登录参数已解析: UserName={userNameParam?.Value}, Password={(passwordParam?.Value != null ? "********" : "null")}"); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"解析登录参数异常: {ex.Message}"); } } // 从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数据,提前返回 } // 读取请求body context.Request.EnableBuffering(); context.Request.Body.Position = 0; using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true)) { var body = reader.ReadToEndAsync().Result; if (!string.IsNullOrEmpty(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")) { // 尝试构建符合接口要求的JSON对象 var jsonObj = new { methodName = formDatas["methodName"], data = formDatas["data"] }; 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 { var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(formDatas); dataModel.RawJsonData = jsonString; System.Diagnostics.Debug.WriteLine($"使用formDatas序列化作为JObject参数: {jsonString}"); } } context.Request.Body.Position = 0; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"处理JObject参数异常: {ex.Message}"); dataModel.RawJsonData = Newtonsoft.Json.JsonConvert.SerializeObject(formDatas); } } } else if (dataModel!.DefaultParameters != null) { if (interInfo.IsAttributeMethod==true) { // } else { dataModel!.DefaultParameters = dataModel?.DefaultParameters?.Where(it => NoPageParameters(it)).ToList(); } foreach (var item in dataModel?.DefaultParameters ?? new List()) { UpdateWhereItemValue(context, formDatas, item); } } } private static bool IsJObjct(DataModel? dataModel, Dictionary formDatas) { if (dataModel?.DefaultParameters == null || !dataModel.DefaultParameters.Any()) return false; var firstParam = dataModel.DefaultParameters.First(); // 检查是否是JToken或其子类型 bool isJTokenType = firstParam.ValueType == nameof(JObject) || firstParam.ValueType == nameof(JToken) || firstParam.ValueType == "JTokenType" || firstParam.ValueType == "Json" || (firstParam.ValueType?.Contains("JToken") == true) || (firstParam.ValueType?.Contains("JObject") == true); bool isSingleParam = dataModel.DefaultParameters.Count == 1; // 检查bodyJson bool hasJsonBody = formDatas.ContainsKey("_rawJson"); var isJObject = (isSingleParam && isJTokenType) || hasJsonBody; System.Diagnostics.Debug.WriteLine($"IsJObjct检查: {isJObject}, 参数类型: {firstParam.ValueType}, 有原始JSON: {hasJsonBody}, MethodArgs: {dataModel?.MyMethodInfo?.MethodArgsCount}"); return isJObject; } 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; } if (IsUserName(item)) { var options = SuperAPIModule._apiOptions; item.Value = options?.DatabaseOptions!.GetCurrentUserCallback().UserName; } else if (IsDateTimeNow(item)) { var options = SuperAPIModule._apiOptions; item.Value = DateTime.Now; } else if (IsFile(item)) { item.Value = PubMethod.ConvertFromBase64(item.Value + ""); } // 再次记录处理后的值 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 && it.Name != SuperAPIModule._apiOptions?.InterfaceOptions.PageSizePropName; } private static bool IsUserName(DataModelDefaultParameter item) { return item?.InsertParameter?.IsUserName == true; } private static bool IsDateTimeNow(DataModelDefaultParameter item) { return item?.InsertParameter?.IsDateTimeNow == true; } private bool IsFile(DataModelDefaultParameter item) { return item?.ValueType == "Byte[]"; } private static bool IsDefaultValue(DataModelDefaultParameter item) { return item.Value == null && item.DefaultValue != null; } private string GetParameterValueFromRequest(DataModelDefaultParameter parameter, HttpContext context, Dictionary formDatas) { if (parameter.ValueIsReadOnly) { return parameter.Value + ""; } // 先尝试从查询字符串中获取 string parameterValue = context.Request.Query[parameter.Name]; // 如果查询字符串没有,再尝试从表单数据中获取 if (string.IsNullOrEmpty(parameterValue)) { 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; } private static Dictionary GetFormDatas(HttpContext context) { Dictionary formDatas = new Dictionary(); if (context.Request.Body != null) { AddFormData(context, formDatas); AddRawParameters(context, formDatas); } return formDatas ?? new Dictionary(); } private static void AddFormData(HttpContext context, Dictionary formDatas) { if (IsFormData(context)) { var formParams = context.Request.Form; foreach (var key in formParams.Keys) { formDatas[key] = formParams[key]; } } } private static void AddRawParameters(HttpContext context, Dictionary formDatas) { try { context.Request.EnableBuffering(); context.Request.Body.Position = 0; string body; using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true)) { body = reader.ReadToEndAsync().Result; } context.Request.Body.Position = 0; if (!string.IsNullOrEmpty(body)) { System.Diagnostics.Debug.WriteLine($"原始请求体: {body}"); // 检查是否是有效的JSON格式 if ((body.StartsWith("{") && body.EndsWith("}")) || (body.StartsWith("[") && body.EndsWith("]"))) { // 保存原始JSON,仅当不需要将其解析为字典时使用 formDatas["_rawJson"] = body; // 检查请求头,如果是 application/json,并且第一个参数是预期为JObject类型, // 则不要解析为字典,避免重复处理,以防止在BindDefaultParameters中的JObject处理逻辑冲突 var contentType = context.Request.ContentType?.ToLower() ?? ""; if (contentType.Contains("application/json")) { // 在JObject处理中,我们会直接使用_rawJson,所以这里不需要解析为字典 // 仅保存原始JSON足够了 System.Diagnostics.Debug.WriteLine("检测到JSON内容类型,保留原始JSON供JObject处理"); return; } try { var bodyParams = Newtonsoft.Json.JsonConvert.DeserializeObject>(body); if (bodyParams != null) { foreach (var item in bodyParams) { if (!formDatas.ContainsKey(item.Key)) { formDatas[item.Key] = item.Value; } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"解析请求体异常: {ex.Message}"); // 如果解析为字典失败,原始JSON已保存 } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"处理请求体异常: {ex.Message}"); } } private static bool IsFormData(HttpContext context) { var contentTypes = new List() { "multipart/form-data", "application/x-www-form-urlencoded" }; 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(); } } } }