using Hh.Mes.Common.config; using Hh.Mes.Common.Json; using Hh.Mes.Service.Configure; using Hh.Mes.Service.SystemAuth; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Net.Http.Headers; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; namespace WebMvc.Aop { /// <summary> /// 操作记录日志 /// action 请求前,请求后 /// </summary> public class OperLogFilter : ActionFilterAttribute { #region property /// <summary> /// action 请求参数 /// </summary> private string actionArguments { get; set; } private Stopwatch Stopwatch { get; set; } /// <summary> /// ioc 数据库访问层注入 /// </summary> private readonly WorkshopService _app; /// <summary> /// action操作 标识 (新增,删除,编辑,上传等等) /// </summary> private static Dictionary<string, string> operType { get; set; } /// <summary> /// 请求体上下文 /// </summary> private HttpContext httpContext { get; set; } /// <summary> /// 用户信息 /// </summary> private AuthStrategyContext currentUser { get; set; } #endregion public OperLogFilter(WorkshopService workshopService, IAuth authUtil) { _app = workshopService; operType = ConfigRead.GetInstance.GetOperType(); currentUser = authUtil.GetCurrentUser(); } public override void OnActionExecuting(ActionExecutingContext context) { base.OnActionExecuting(context); Stopwatch = new Stopwatch(); Stopwatch.Start(); httpContext = context.HttpContext; actionArguments = JsonConvert.SerializeObject(context.ActionArguments).Replace("\r", "").Replace("\n", ""); } public override void OnActionExecuted(ActionExecutedContext context) { base.OnActionExecuted(context); Stopwatch.Stop(); //Net Core 2.1Filter里面获取Controller、Action,请求方法,请求头部,请求参数 //https://blog.csdn.net/mango_love/article/details/84992020 var description = (ControllerActionDescriptor)context.ActionDescriptor; var actionName = description.ActionName; var otype = operType.ContainsKey(actionName) ? operType[actionName] : "其他"; dynamic response; if (context.HttpContext.Request.Method.ToLower() == "get") { if (otype == "查看") { response = ""; } else { var temp = context.Result as ObjectResult; response = IsPropertyExist(temp, "Value") ? temp.Value : "在返回结果后发生了异常Get"; } } else { dynamic result = context.Result; response = IsPropertyExist(result, "Value") ? result.Value : "在返回结果前发生了异常"; } InserSysoperLog(otype, response, Stopwatch.Elapsed.TotalSeconds); } #region 自定义方法 /// <summary> /// 写入日志 异步 /// </summary> private void InserSysoperLog(string otype, dynamic response, double TotalSeconds) { bool isOk = response is string; if (!isOk) response = JsonHelper.Instance.Serialize(response); string url = httpContext.Request.Host + httpContext.Request.Path + httpContext.Request.QueryString; var dc = new Dictionary<string, object> { {"url", url}, {"operType", otype}, {"method", httpContext.Request.Method}, {"request",httpContext.Request.Headers[HeaderNames.UserAgent].ToString()}, {"parameter", actionArguments}, {"response", response}, {"totalMilliseconds", TotalSeconds}, {"logTime", DateTime.Now}, {"name", currentUser.User.Name}, {"ip", httpContext.Connection.RemoteIpAddress.ToString()}, {"createTime", DateTime.Now}, {"createBy", currentUser.User.Account} }; //字典 异步写入日志 _app.GetContext().Insertable(dc).AS("sys_oper_log").ExecuteCommandAsync(); } /// <summary> /// 动态类型 dynamic 是否存在某个属性 /// </summary> public static bool IsPropertyExist(dynamic data, string propertyname) { if (data == null) return false; if (data is ExpandoObject) return ((IDictionary<string, object>)data).ContainsKey(propertyname); return data.GetType().GetProperty(propertyname) != null; } #endregion } }