using Attribute; using Base; using Common; using Extensions; using Infrastructure; using Infrastructure.Model; using IPTools.Core; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Diagnostics; using Microsoft.AspNetCore.Mvc.Filters; using NLog; using System.Text; using System.Web; namespace Middleware { public class GlobalActionMonitor : ActionFilterAttribute { static readonly Logger logger = LogManager.GetCurrentClassLogger(); // private readonly ISysOperLogService OperLogService; public GlobalActionMonitor() { // OperLogService = operLogService; } /// /// Action请求前 /// /// /// /// public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if(context.HttpContext.Request.Path.Value.ToLower().Contains("v1/")) { string content = ""; if(context.HttpContext.Request.Method.ToLower() == "get") { content = context.HttpContext.GetQueryString(); content = content.Substring(content.IndexOf("?") + 1); if(!string.IsNullOrEmpty(content)) { string jsonString = ""; string[] dataList = content.Split('&'); foreach(string sub in dataList) { string[] item = sub.Split('='); jsonString += "\"" + item[0] + "\":\"" + item[1] + "\","; } content = "{" + jsonString.TrimEnd(',') + "}"; } } else if(context.HttpContext.Request.Method.ToLower() == "delete") { string path = context.HttpContext.Request.Path.Value; content = path.Substring(path.LastIndexOf("/") + 1); } else { content = context.HttpContext.GetBody(); } if(!string.IsNullOrEmpty(content)) { if(content.Contains("{") && content.Contains("}") && content != "{}") { Dictionary dictionary = Newtonsoft.Json.JsonConvert.DeserializeObject>(content); if(context.ActionDescriptor.Parameters.Count > 0) { var parameters = context.ActionDescriptor.Parameters; foreach(var parameter in parameters) { string parameterName = parameter.Name; Type objectType = parameter.ParameterType; if(objectType.FullName != "System.String") { System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(objectType); var entry = assembly.CreateInstance(objectType.FullName); Type type = entry.GetType(); System.Reflection.PropertyInfo[] propertyInfos = type.GetProperties(); for (int i = 0; i < propertyInfos.Length; i++) { foreach (string key in dictionary.Keys) { if (propertyInfos[i].Name == key) { object value = dictionary[key]; string ParameterType = propertyInfos[i].GetMethod.ReturnParameter.ParameterType.Name; if (ParameterType == "Int32") { if(value == null || value == "") value = "0"; value = Convert.ToInt32(value); } else if (ParameterType == "Int64") { if(value == null || value == "") value = "0"; value = Convert.ToInt64(value); } else if (ParameterType == "Decimal") { if(value == null || value == "") value = "0"; value = Convert.ToDecimal(value); } else if(ParameterType == "Boolean") { if(value == null || value == "") value = false; } else if (ParameterType == "Int64[]") { value = Tools.SpitLongArrary(Newtonsoft.Json.JsonConvert.SerializeObject(value).Replace("[", "").Replace("]", "").Trim('"'), ','); } else if (ParameterType == "Int32[]") { value = Tools.SpitIntArrary(Newtonsoft.Json.JsonConvert.SerializeObject(value).Replace("[", "").Replace("]", "").Trim('"'), ','); } else if (ParameterType == "List`1") { string val = Newtonsoft.Json.JsonConvert.SerializeObject(value).Replace("[", "").Replace("]", "").Trim('"'); value = Tools.SpitLongArrary(val, ',').ToList(); } else if(ParameterType == "Nullable`1") { string fullName = Function.CheckNull(propertyInfos[i].GetMethod.ReturnParameter.ParameterType.FullName); if(fullName.Contains("System.Int32")) { if(value == null) { value = -99; } else { value = Convert.ToInt32(value); } } } if(value.ToString() == "-1") value = -1; if(value.ToString() == "[]") value = ""; propertyInfos[i].SetValue(entry, value, null); break; } } } if(context.ActionArguments.ContainsKey(parameterName)) { context.ActionArguments[parameterName] = entry; } else { context.ActionArguments.Add(parameterName, entry); } } } } } else { string ParamName = context.ActionDescriptor.Parameters[0].Name; if(context.ActionArguments.ContainsKey(ParamName)) { context.ActionArguments[ParamName] = Convert.ToInt32(content); } else { context.ActionArguments.Add(ParamName, Convert.ToInt32(content)); } } } else { if(context.ActionDescriptor.Parameters.Count > 0) { string ParamName = context.ActionArguments.Keys.First(); object ParamValue = context.ActionArguments.Values.First(); // ParamValue = DesDecrypt(ParamValue.ToString()); if(ParamValue.GetType() == typeof(int)) { ParamValue = (int)ParamValue; } if(context.ActionArguments.ContainsKey(ParamName)) { context.ActionArguments[ParamName] = ParamValue; } else { context.ActionArguments.Add(ParamName, ParamValue); } } } } string msg = string.Empty; var values = context.ModelState.Values; foreach (var item in values) { foreach (var err in item.Errors) { if (!string.IsNullOrEmpty(msg)) { msg += " | "; } msg += err.ErrorMessage; } } if (!string.IsNullOrEmpty(msg)) { ApiResult response = new((int)ResultCode.PARAM_ERROR, msg); context.Result = new JsonResult(response); } return base.OnActionExecutionAsync(context, next); } /// /// OnActionExecuted是在Action中的代码执行之后运行的方法。 /// /// public override void OnResultExecuted(ResultExecutedContext context) { if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return; //获得注解信息 // LogAttribute logAttribute = GetLogAttribute(controllerActionDescriptor); // if (logAttribute == null) return; try { string method = context.HttpContext.Request.Method.ToUpper(); // 获取当前的用户 string userName = context.HttpContext.GetName() ?? context.HttpContext.Request.Headers["userName"]; string jsonResult = string.Empty; if (context.Result is ContentResult result && result.ContentType == "application/json") { jsonResult = result.Content.Replace("\r\n", "").Trim(); } if (context.Result is JsonResult result2) { jsonResult = result2.Value?.ToString(); } //获取当前执行方法的类名 //string className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name; //获取当前成员的名称 //string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name; string controller = context.RouteData.Values["Controller"].ToString(); string action = context.RouteData.Values["Action"].ToString(); string ip = HttpContextExtension.GetClientUserIp(context.HttpContext); // var ip_info = IpTool.Search(ip); // SysOperLog sysOperLog = new() // { // Status = 0, // OperName = userName, // OperIp = ip, // OperUrl = HttpContextExtension.GetRequestUrl(context.HttpContext), // RequestMethod = method, // JsonResult = jsonResult, // OperLocation = HttpContextExtension.GetIpInfo(ip), // Method = controller + "." + action + "()", // //Elapsed = _stopwatch.ElapsedMilliseconds, // OperTime = DateTime.Now, // OperParam = HttpContextExtension.GetRequestValue(context.HttpContext, method) // }; // if (logAttribute != null) // { // sysOperLog.Title = logAttribute?.Title; // sysOperLog.BusinessType = (int)logAttribute.BusinessType; // sysOperLog.OperParam = logAttribute.IsSaveRequestData ? sysOperLog.OperParam : ""; // sysOperLog.JsonResult = logAttribute.IsSaveResponseData ? sysOperLog.JsonResult : ""; // } LogEventInfo ei = new(NLog.LogLevel.Info, "GlobalActionMonitor", ""); ei.Properties["jsonResult"] = !HttpMethods.IsGet(method) ? jsonResult : ""; // ei.Properties["requestParam"] = sysOperLog.OperParam; ei.Properties["user"] = userName; logger.Log(ei); // OperLogService.InsertOperlog(sysOperLog); } catch (Exception ex) { logger.Error(ex, $"记录操作日志出错了#{ex.Message}"); } } private LogAttribute GetLogAttribute(ControllerActionDescriptor controllerActionDescriptor) { var attribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true) .FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute))); return attribute as LogAttribute; } private string DesDecrypt(string content) { content = HttpUtility.UrlDecode(content); return Dbconn.DesDecrypt(content, AppSettings.GetConfig("ApiKey")); } } }