Action过滤器
在ASP.NET Core中,Action过滤器用于在执行Action方法之前或之后执行逻辑。你可以创建自定义的Action过滤器来实现这一点。
继承 ActionFilterAttribute 类:
cs
[TypeFilter(typeof(CustomAllActionResultFilterAttribute))]
public IActionResult Index4(int i)
{
return Json(new
{
Id = 1,
Name = "Tom",
Age = 18
});
}
写日志
cs
public class CustomAllActionResultFilterAttribute:ActionFilterAttribute
{
private readonly ILogger<CustomAllActionResultFilterAttribute> _ILogger;
public CustomAllActionResultFilterAttribute(ILogger<CustomAllActionResultFilterAttribute> iLogger)
{
this._ILogger = iLogger;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var para = context.HttpContext.Request.QueryString.Value;
var controllerName = context.HttpContext.GetRouteValue("controller");
var actionName = context.HttpContext.GetRouteValue("action");
_ILogger.LogInformation($"执行{controllerName}控制器--{actionName}方法;参数为:{para}");
}
public override void OnActionExecuted(ActionExecutedContext context)
{
var result = Newtonsoft.Json.JsonConvert.SerializeObject(context.Result);
var controllerName = context.HttpContext.GetRouteValue("controller");
var actionName = context.HttpContext.GetRouteValue("action");
_ILogger.LogInformation($"执行{controllerName}控制器--{actionName}方法:执行结果为:{result}");
}
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var controllerName = context.HttpContext.GetRouteValue("controller");
var actionName = context.HttpContext.GetRouteValue("action");
var para = context.HttpContext.Request.QueryString.Value;
_ILogger.LogInformation($"执行{controllerName}控制器--{actionName}方法;参数为:{para}");
ActionExecutedContext executedContext = await next.Invoke(); //这句话执行就是去执行Action
var result = Newtonsoft.Json.JsonConvert.SerializeObject(executedContext.Result);
_ILogger.LogInformation($"执行{controllerName}控制器--{actionName}方法:执行结果为:{result}");
}
public override void OnResultExecuting(ResultExecutingContext context)
{
base.OnResultExecuting(context);
}
public override void OnResultExecuted(ResultExecutedContext context)
{
base.OnResultExecuted(context);
}
public override Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
return base.OnResultExecutionAsync(context, next);
}
}
AlwaysRunResultFilter扩展定制
在之前学过的ActionFilter/ResourceFilter中只要是对HttpContext.Result赋值,就不再继续往后了。
在ASP.NET Core中,AlwaysRunResultFilter
是一个实现了IAlwaysRunResultFilter
接口的特性,它用于在执行结果执行之后执行一些操作,无论结果是否执行成功。
cs
[CustomCacheResourceFilter]
[CustomAlwaysRunResultFilter]
public IActionResult Index5()
{
return Json(new
{
Id =1,
Name ="Tom",
Age = 18
});
}
cs
public class CustomAlwaysRunResultFilterAttribute : Attribute, IAlwaysRunResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
Console.WriteLine("CustomAlwaysRunResultFilterAttribute.OnResultExecuting");
}
public void OnResultExecuted(ResultExecutedContext context)
{
Console.WriteLine("CustomAlwaysRunResultFilterAttribute.OnResultExecuted");
}
}
Filter的多种注册
AOP:在不修改之前的代码为基础上,动态增加功能,但是我们现在做的无论是ResourceFilter还是ActionFilter都是直接标记在方法上的,现在需要的是对某一些Action、或者对于某个项目整体生效。
方法注册:仅对当前方法生效
cs
[CustomCacheResourceFilter]
[CustomAlwaysRunResultFilter]
public IActionResult Index5()
{
return Json(new
{
Id =1,
Name ="Tom",
Age = 18
});
}
控制器(类)注册:对当前控制器下的所有Action都生效
全局注册:对于项目中的所有方法都生效,在Program.cs文件
cs
// Add services to the container.
builder.Services.AddControllersWithViews(mvcOptions =>
{
// 3.全局注册--对整个项目都生效的
mvcOptions.Filters.Add<CustomCacheResourceFilterAttribute>();
});
匿名支持
单个Action注册是对于某一个Action生效,但是控制器、全局注册都是生效一大片。
那么在这样生效一部分中,如果希望在全局或者控制器注册后,其中有部分Action不生效,该怎么处理。(匿名支持)
系统提供了AllowAnonymousAttribute,有部分可以使用,有部分不能直接使用。
cs
namespace Learn.NET6.Project.Utility.Filters
{
public class CustomAllowAnonymousAttribute: Attribute
{
}
}
cs
#region 匿名支持
/// <summary>
/// 不支持缓存
/// </summary>
/// <returns></returns>
//[AllowAnonymous]
[CustomAllowAnonymous]
public IActionResult Index6()
{
return Json(new
{
Id =1,
Name ="Tom",
Age=18
});
}
#endregion