.Net6对AOP的多种支持之IActionFilter
环境: .Net6 windows10 Web项目
开发工具: Vs2022
IAcIActionFilter(日志同步实现)
IActionFilter概念
ASP.NET Core6提供的是接口IActionFilter/ActionFilterAttribute
系统框架提供的抽象(接口(同步实现和异步实现)/抽象类),可以是自定义扩展,也可以直接使用
通过一个特性的支持
作用是做日志,更加贴合Action,缓存也能做,但是专人做专事,用它来做日志会更好
执行顺序
A 先执行构造函数
B 再执行OnActionExecuting(在xxAction之前)
C 执行Action
D 最后执行OnActionExecuted(在xxAction之后)
实现IActionFilter
1定义特性类
名称以Attribute结尾(标记特性时可以省略),继承Attribute、IActionFilter(并实现该接口)
public class CustomIActionFilecuting(ActionExecutingContext context)
这里的执行顺序会是在构造函数执行以后,Action执行之前执行
3 OnActionExecuted(在xxAcion之后)
public void OnActionExecuted(ActionExecutedContext context)
这里的执行顺序会是在Action执行完毕以后执行
5 加入特性标记
在需要做日志的方法上标记特性
[TypeFilter(typeof(CustomIActionFilterAttribute))]
public IActionResult index3(int id ){
return View();
}
完整代码示例
CustomIActionFilterAttribute 类
/// <summary> /// ActionFilter写入Log4net /// </summary> public class CustomIActionFilterAttribute : Attribute, IActionFilter { //构造函数注入1:创建只读私有私有属性 private readonly ILogger<CustomIActionFilterAttribute> _logger; /// <summary> /// 构造函数赋值 /// </summary> /// <param name="logger"></param> public CustomIActionFilterAttribute(ILogger<CustomIActionFilterAttribute> logger) { this._logger = logger; } /// <summary> /// 在xxAction 之后 /// </summary> /// <param name="context"></param> /// <exception cref="NotImplementedException"></exception> public void OnActionExecuted(ActionExecutedContext context) { Console.WriteLine("之后"); var controllerName = context.HttpContext.GetRouteValue("controller"); var actionName = context.HttpContext.GetRouteValue("action"); var result = Newtonsoft.Json.JsonConvert.SerializeObject(context.Result); _logger.LogInformation($"执行{controllerName}控制器的{actionName}方法,结果是:{result}"); } /// <summary> /// 在xxAction之前 /// </summary> /// <param name="context"></param> /// <exception cref="NotImplementedException"></exception> public void OnActionExecuting(ActionExecutingContext context) { var para = context.HttpContext.Request.QueryString.Value; var controllerName = context.HttpContext.GetRouteValue("controller"); var actionName = context.HttpContext.GetRouteValue("action"); _logger.LogInformation($"执行{controllerName}控制器的{actionName}方法,参数是:{para}"); Console.WriteLine("之前"); } }
Controller
[TypeFilter(typeof(CustomIActionFilterAttribute))] public IActionResult index3(int id ) { ViewBag.user = Newtonsoft.Json.JsonConvert.SerializeObject(new { Id = id, Name = "John--ViewBag", Age = 18 }); ViewData["UserInfo"] = Newtonsoft.Json.JsonConvert.SerializeObject(new { Id = id, Name = "John --ViewData", Age = 18 }); return View(); }
IActionFilter更适合做日志的原因
更加贴合Action
这一点我们可以从执行的顺序可以看到,IAction的执行顺序是先执行构造函数,再执行OnActionExecuting(在xxAction之前),然后执行
ACtion,执行完毕后再执行最后执行OnActionExecuted(在xxAction之后)。IAction将Action包裹且最贴近,比如前台传递过来的值,或许经过一系列处理后,值发生了变化,而IActionFilter无疑是可以记录最真实的