为了实现自己的操作日志记录功能,我有个思路:
- 自定义特性ActionAttribute;
- 在每个控制器方法上加上自定义特性;
- 通过中间件,在每个控制器方法执行完后,获取该特性信息,写入数据库;
首先,自定义特性ActionAttribute.cs
public class ActionAttribute : Attribute
{
public string ActionName { get; set; }
public ActionAttribute(string actionName)
{
ActionName = actionName;
}
}
自定义中间件类:ActionLogMiddleware.cs
public class ActionLogMiddleware
{
private readonly RequestDelegate _next;
private readonly ActionLogService _service;
public ActionLogMiddleware(RequestDelegate next, ActionLogService actionLogService)
{
_next = next;
_service = actionLogService;
}
public async Task InvokeAsync(HttpContext context)
{
var endpoint = GetEndpoint(context);
var username = "未知用户";
if (endpoint != null)
{
var actionAttribute = endpoint.Metadata.GetMetadata<ActionAttribute>();
if (actionAttribute != null)
{
var actionName = actionAttribute.ActionName;
ActionLog log = new ActionLog
{
Action = actionName,
ActionTime = DateTime.Now,
Username = username,
IP = ip,
};
await _service.Add(log);
}
}
await _next(context);
}
public static Endpoint GetEndpoint(HttpContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return context.Features.Get<IEndpointFeature>()?.Endpoint;
}
}
扩展方法,方便激活自定义中间件:ActionLogMiddlewareExtensions.cs
public static class ActionLogMiddlewareExtensions
{
public static IApplicationBuilder UseActionLog(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<ActionLogMiddleware>();
}
}
最后,在Startup.cs中激活自定义中间件
app.UseActionLog();
使用方法,在控制器的各个方法上加上【ActionAttribute】
[Action("删除公告")]
public async Task<ActionResult<int>> Delete(int id)
{
var model = await _service.GetById(id);
if (model == null)
{
return NotFound();
}
return await _service.Delete(model);
}