通过Attribute和结果过滤器记录用户操作记录
/// <summary> /// 用户操作记录 /// </summary> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class OperationLogAttribute : Attribute, IResultFilter { public readonly string _description; public OperationLogAttribute(string description) { _description = description; } /// <summary> /// 执行完成 /// </summary> /// <param name="context"></param> public async void OnResultExecuted(ResultExecutedContext context) { try { context.HttpContext.Request.EnableBuffering(); var userId = context.HttpContext?.User.GetUserId() ?? -1; var userName = context.HttpContext?.User.GetUserName() ?? string.Empty; var companyId = context.HttpContext?.User.GetCompanyId() ?? -1; var requestInfo = await ReadRequest(context.HttpContext); var path = context.HttpContext.Request.Path.Value ?? string.Empty; var config = Appsettings.GetConfig<DbConfig>("DbConfig"); OperationLogInfo operation = new OperationLogInfo(Guid.NewGuid().ToString(), userId, companyId, requestInfo, path, _description, userName, DateTime.Now); await StoreReceivedMessage(operation); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } public void OnResultExecuting(ResultExecutingContext context) { } private async Task StoreReceivedMessage(OperationLogInfo operation) { object[] sqlParams = { new MySqlParameter("@operation_log_id", operation.OperationLogId), new MySqlParameter("@user_id", operation.UserId), new MySqlParameter("@user_name", operation.UserName), new MySqlParameter("@company_id", operation.CompanyId), new MySqlParameter("@request_content", operation.RequestContent), new MySqlParameter("@description", operation.Description), new MySqlParameter("@request_path", operation.RequestPath), new MySqlParameter("@create_time", operation.CreateTime), new MySqlParameter("@update_time", operation.CreateTime), new MySqlParameter("@is_deleted", operation.IsDeleted), }; var sql = $@"INSERT INTO `uc_operation_log`(`operation_log_id`,`user_id`,`user_name`,`company_id`,`request_content`,`request_path`,`description`,`create_time`,`update_time`,`is_deleted`) " + $"VALUES(@operation_log_id,@user_id,@user_name,@company_id,@request_content,@request_path,@description,@create_time,@update_time,@is_deleted);"; var config = Appsettings.GetConfig<DbConfig>("DbConfig"); var connection = new MySqlConnection(config.ConnectionString); await using var _ = connection.ConfigureAwait(false); await connection.ExecuteNonQueryAsync(sql, sqlParams: sqlParams).ConfigureAwait(false); } /// <summary> /// 读取数据 /// </summary> /// <param name="context"></param> /// <returns></returns> private async Task<string> ReadRequest(HttpContext context) { var request = context.Request; // request.EnableBuffering(); is necessary for reading the Body stream more than once // You need to move the position back to the beginning, otherwise the next pice of middleware // that try to get the body will fail to do that, i.e. the position is in the end and thus the // body seems to be empty request.Body.Position = 0; var buffer = new byte[Convert.ToInt32(request.ContentLength)]; await request.Body.ReadAsync(buffer, 0, buffer.Length); var bodyAsText = Encoding.UTF8.GetString(buffer); return bodyAsText; } }