.Net core中使用过滤器

.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))],可以没有无参数构造函数,可以支持依赖注
入,但是必须要注册服务
原文地址:https://www.cnblogs.com/wangjinya/p/14466796.html