.Net core中使用过滤器
一、.NET5 AOP 5个Filter
- AuthorizationFilter 鉴权授权
- ResourceFilter 资源
- ExceptionFilter 异常
- ActionFilter 方法
- ResultFilter 结果
特点:
ActionFilter的特点自定义一个CustomActionFilterAttribute特性,继承Attribute,实现IActionFilter接口;实现方法,标记在Action上;
二、定义一个CustomActionFilterAttribute,并且实现其中代码
//方法过滤器,这个是没有构造函数的
public class CustomActionFilterAttribute : Attribute, IActionFilter { /// <summary> /// 方法执行前 /// </summary> /// <param name="context"></param> public void OnActionExecuting(ActionExecutingContext context) { ///记录请求来了之后的一些参数: //参数 Newtonsoft.Json.JsonConvert.SerializeObject(context.HttpContext.Request.Query); throw new NotImplementedException(); } /// <summary> /// 方法执行后 /// </summary> /// <param name="context"></param> public void OnActionExecuted(ActionExecutedContext context) { Newtonsoft.Json.JsonConvert.SerializeObject(context.Result); throw new NotImplementedException(); } }
有构造函数的过滤器
public class CustomActionFilterAttribute : Attribute, IActionFilter { public ILogger<CustomActionFilterAttribute> _iLoggerProp { get; set; } private ILogger<CustomActionFilterAttribute> _iLogger = null; public CustomActionFilterAttribute(ILogger<CustomActionFilterAttribute> logger) { _iLogger = logger; } /// <summary> /// 方法执行前 /// </summary> /// <param name="context"></param> public void OnActionExecuting(ActionExecutingContext context) { if (context.ActionDescriptor.EndpointMetadata.Any(item=>item.GetType()==typeof(CustomAllowAnonymousAttribute))) //如果标记的有特殊的记号,就避开检查; { return; } _iLoggerProp.LogInformation("支持属性注入。。。"); ///记录请求来了之后的一些参数: //参数 Newtonsoft.Json.JsonConvert.SerializeObject(context.HttpContext.Request.Query) //log4net; _iLogger.LogInformation(Newtonsoft.Json.JsonConvert.SerializeObject(context.HttpContext.Request.Query)); _iLogger.LogInformation("CustomActionFilterAttribute.OnActionExecuting"); } /// <summary> /// 方法执行后 /// </summary> /// <param name="context"></param> public void OnActionExecuted(ActionExecutedContext context) { _iLogger.LogInformation(Newtonsoft.Json.JsonConvert.SerializeObject(context.Result)); _iLogger.LogInformation("CustomActionFilterAttribute.OnActionExecuted"); } }
三、 使用过滤器的方式
1.[CustomActionFilter]---Fitler必须有无参数构造函数
2.[TypeFilter(typeof(CustomActionFilterAttribute))],可以没有无参数构造函数,可以支持依赖注入
3.[ServiceFilter(typeof(CustomActionFilterAttribute))],可以没有无参数构造函数,可以支持依赖注入,但是必须要注册服务
注册服务如下:
#region 支持Filter依赖注入 containerBuilder.RegisterType(typeof(CustomActionFilterAttribute)).PropertiesAutowired(); #endregion
相关实例如下:
//过滤器中不需要构造函数的时候使用这个,反之就使用后面两个 //[CustomActionFilter] //[TypeFilter(typeof(CustomActionFilterAttribute))] //可以支持依赖注入 [ServiceFilter(typeof(CustomActionFilterAttribute))] [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); }
四、Filter的生效范围
1.标记在Action上,就只对当前Action生效
2.标记在Controller上,就对Controller上中的所有Action生效
3.全局注册,对于当前整个项目中的Action都生效,在ConfigureServices中增加以下代码即可
services.AddMvc(option=> {
option.Filters.Add<CustomActionFilterAttribute>(); //全局注册:
});
五、Filter匿名
如果全局注册,Filter生效于所有的Acion;如果有部分Action我希望你不生效呢?怎么办呢?
匿名----可以避开Filter的检查;
如何支持自定义的Filter,匿名
1.自定义一个特性;
2.在需要匿名的Filter内部,检查是否需要匿名(检查是否标记的有匿名特性),如果有就直接避开
if (context.ActionDescriptor.EndpointMetadata.Any(item=>item.GetType()==typeof(CustomAllowAnonymousAttribute))) //如果标记的有特殊的记号,就避开检查; { return; }
六、以下是一个相关完整的实例:注意该示例仅限用于不分离的项目中,如果后端是webApi,很可能无法应用。
1. 异常过滤器相关代码
/// <summary> /// 异常过滤器 /// </summary> public class CustomActionFilterAttribute : Attribute, IActionFilter { /// <summary> /// 方法执行前 /// </summary> /// <param name="context"></param> public void OnActionExecuting(ActionExecutingContext context) { if (context.ActionDescriptor.EndpointMetadata.Any(item => item.GetType() == typeof(CustomAllowAnonymousAttribute))) //如果标记的有特殊的记号,就避开检查; { return; } Byte[] bytes; context.HttpContext.Session.TryGetValue("CurrentUser", out bytes); //base.HttpContext.SetCookies() string cookieKey = CookieSessionHelper.GetCookiesValue(context.HttpContext, "CurrentUser"); string str = cookieKey != null ? new SessionHelper(context.HttpContext).GetSession(cookieKey) : null; if (string.IsNullOrEmpty(str)) { var result = new ViewResult { ViewName = "~/Views/SessionLogin/SessionLogins.cshtml" }; //result.ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState); //result.ViewData.Add("Exception", context.Exception); context.Result = result; //断路器---只要对Result赋值--就不继续往后了; } Console.WriteLine("这是方法执行前"); } /// <summary> /// 方法执行后 /// </summary> /// <param name="context"></param> public void OnActionExecuted(ActionExecutedContext context) { if (context.ActionDescriptor.EndpointMetadata.Any(item => item.GetType() == typeof(CustomAllowAnonymousAttribute))) //如果标记的有特殊的记号,就避开检查; { return; } Console.WriteLine("这是方法执行后"); } }
第一种注册方式-全局注册
services.AddMvc(option => { option.Filters.Add<CustomActionFilterAttribute>(); //全局注册: option.Filters.Add<CustomExceptionFilterAttribute>(); //全局注册异常过滤器: });
第二种 局部注册
1.[CustomActionFilter]---Fitler必须有无参数构造函数 2.[TypeFilter(typeof(CustomActionFilterAttribute))],可以没有无参数构造函数,可以支持依赖注入 3.[ServiceFilter(typeof(CustomActionFilterAttribute))],可以没有无参数构造函数,可以支持依赖注 入,但是必须要注册服务