• .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))],可以没有无参数构造函数,可以支持依赖注
    入,但是必须要注册服务
  • 相关阅读:
    POJ 2342.Anniversary party-树形dp
    Codeforces Round #363 (Div. 2) A、B、C
    Codeforces Beta Round #17 D.Notepad 指数循环节
    hdu 5920 Wool 思路
    hdu 5719 Arrange 贪心
    hdu 5718 Oracle 高精度
    hiho #1332 : 简单计算器 栈+递归
    UESTC 1074 秋实大哥搞算数 栈模拟
    cdoj 1329 卿学姐与魔法 优先队列
    cdoj 1324 卿学姐与公主 线段树裸题
  • 原文地址:https://www.cnblogs.com/wangjinya/p/14466796.html
Copyright © 2020-2023  润新知