.Net core---Filter2

Filter的生效范围和执行顺序

1.标记在Action上,就只对当前Action生效


2.标记在Controller上,就对controller上中的所有Action生效

 

 3.全局注册,对于当前整个项目中的Action都生效

startup.cs 中ConfigureServices方法

services.AddMvc(option=>
            {
                option.Filters.Add<CustomActionFilterAttribute>();//全局注册
            });

定义三个ActionFilter,分别注册全局,控制器,Action
执行顺序如下:
1.控制器实例化
2.全局注册的Filter-- OnActionExecuting
3.控制器注册的Filter-OnActionExecuting
4_Actioin注册的Filter-OnActionExecuting
5.执行Action内部的逻辑算计
6.Action注册的Filter-OnActionExeculed
7.控制器注册的Filter-OnActionExecuted
8.全局注册的Filter. OnActionExecuted

 执行顺序可以更改

 在注册Filter的时候,指定Order的值, 执行顺序,按照Order的值,从小到大执行;

1.实现接口ActionFilterAttribute

 public class CustomGlobalActionFilterAttribute :ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine("CustomGlobalActionFilterAttribute.OnActionExecuted");
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine("CustomGlobalActionFilterAttribute.OnActionExecuting");
        }
    }

2.使用Order改变顺序 

 结果

ResourceFilter
就是为了缓存而存在.

当经过授权验证后,进入ResourceFilter 如果有缓存,就立马返回,不继续执行下去 。没有缓存就一步一步走下去。

练习

1.新建一个ResourceFilter的类,实现IResourceFilter接口

 public class CustomResourceFilterAttribute : Attribute, IResourceFilter
    {
        private static Dictionary<string, object> CacheDictionary = new Dictionary<string, object>();
        /// <summary>
        /// 在XXX资源之前执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            //这里就判断是否有缓存,只要是key 不变,缓存就不变
            string key = context.HttpContext.Request.Path;
            if (CacheDictionary.Any(item=>item.Key==key))
            {
                //断路器,只要是对Result赋佰,就不继续往后走了
                context.Result = CacheDictionary[key] as IActionResult;
            }
            Console.WriteLine("CustomResourceFilterAttribute.OnResourceExecuting");
        }
        /// <summary>
        /// 在XXX资源之后执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            //进入此方法就代表,已经完成了业务处理
            string key = context.HttpContext.Request.Path;
            CacheDictionary[key] = context.Result;

            Console.WriteLine("CustomResourceFilterAttribute.OnResourceExecuted");
        }
    }

2.应用

Filter匿名
如果全局注册,Filter生效于所有的Acion;如果有部分Action不生效,匿名---可以避开Filter的检查;
如何支持自定义的Filter
1.自定义一个特性;

public class CustomAllowAnonymousAttribute:Attribute
    {

    }

2.在需要匿名的Filter内部,检查是否需要匿名(检查是否标记的有匿名特性) ,如果有就直接避开

  public class CustomActionFilterAttribute : Attribute, IActionFilter
    {
        /// <summary>
        /// 方法执行前
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutedContext context)
        {
            if (context.ActionDescriptor.EndpointMetadata.Any(item=>item.GetType()
            ==typeof(
CustomAllowAnonymousAttribute)))//如果有标记的有特殊记号,就避开检查
            {
                return;
            }
        }

 public void OnActionExecuted(ActionExecutingContext context)
        {
        }

}

3.使用

 ExceptionFilter

1.自定义一个CustomExceptionFilterAltribute ,实现lExceptionFilter按口,

  public class CustomExceptionFilterAttribute : Attribute, IExceptionFilter
    {
        private IModelMetadataProvider _modelMetadataProvider = null;
        public CustomExceptionFilterAttribute(IModelMetadataProvider modelMetadataProvider)
        {
            _modelMetadataProvider = modelMetadataProvider;
        }
        /// <summary>
        /// 当异常发生的时候触发到这里处理
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            if (!context.ExceptionHandled)//判断异常是否被处理过
            {
                //在这里处理
                //在这里处理如果 是Ajax请求===返回Json .
                if (this.IsAjaxReguest(context.HttpContext.Request))//header看看是不是XMLHttpRequest
                {
                    context.Result = new JsonResult(new
                    {
                        Result = false,
                        Msg = context.Exception.Message
                    });//中断式---请求到这里结束了,不再继续Action
                }
                else 
                {
                    //跳转到异常页面
                    var result = new ViewResult { ViewName ="~/Views/Shared/Error.cshtml"};
                    result.ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState);
                    result.ViewData.Add("Exception" ,context.Exception) ;

                    context.Result = result; //断路器- --只要对Result赋值-就不继续往后了;

                }
                context.ExceptionHandled = true;//异常已经被处理了
            }
           
        }

        private bool IsAjaxReguest(HttpRequest request)
        {
            string header = request.Headers["X-Requested-With"];
            return "XMLHttpRequest".Equals(header);
        }
    }

2.实现方法,先判断,异常是否被处理过,如果没有被处理过,就处理;
3.分情况处理: 1如果是ajax请求,就返回JosnResult, 如果不是Ajax请求,就返回错误页面
4.全局注册(注册到Action上,只是对action生效)

全局注册--startup.cs 中ConfigureServices方法

 services.AddMvc(option =>
            {
                option.Filters.Add<CustomExceptionFilterAttribute>();//注册全局异常
            });

注册到Action上

 ExceptionFilter能捕捉到哪些异常
1.控制器实例化异常--------------捕捉的到
2.异常发生在Try-cache中-------捕捉的不到
3.在视图中发生异常--------------捕捉的不到
4.Service层发生异常-------------捕捉的到
5.在action中发生异常------------捕捉的到
6.请求错误路径异常--------------可以使用中间件来支持,只要不是200的状态,就可以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值