(精华)2020年8月15日 ASP.NET Core Filter的过滤器使用(ExceptionFilter,ActionFilter,ResourceFilter)

285 阅读1分钟

ExceptionFilter

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
    {
        #region Identity
        private readonly ILogger<CustomExceptionFilterAttribute> _logger;
        private readonly IModelMetadataProvider _modelMetadataProvider;
        public CustomExceptionFilterAttribute(ILogger<CustomExceptionFilterAttribute> logger
            , IModelMetadataProvider modelMetadataProvider)
        {
            this._modelMetadataProvider = modelMetadataProvider;
            this._logger = logger;
        }
        #endregion
        /// <summary>
        /// 异常发生,但是没有处理时
        /// 异常之后得写日志
        /// </summary>
        /// <param name="context"></param>
        public override void OnException(ExceptionContext context)
        {
            if (!context.ExceptionHandled)
            {
                this._logger.LogError($"{context.HttpContext.Request.RouteValues["controller"]} is Error");
                if (this.IsAjaxRequest(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;
                }
                context.ExceptionHandled = true;
            }
        }
        private bool IsAjaxRequest(HttpRequest request)
        {
            string header = request.Headers["X-Requested-With"];
            return "XMLHttpRequest".Equals(header);
        }
    }

ActionFilter

public class CustomActionFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnActionExecuted{this.Order}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnActionExecuting{this.Order}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnResultExecuting{this.Order}");
        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnResultExecuted{this.Order}");
        }
    }

    public class CustomControllerFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuted {this.Order}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuting{this.Order}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuting{this.Order}");
        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuted{this.Order}");
        }
    }

    public class CustomGlobalFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnActionExecuted{this.Order}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnActionExecuting{this.Order}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnResultExecuting{this.Order}");
        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnResultExecuted{this.Order}");
        }
    }
public class CustomActionCacheFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            context.HttpContext.Response.Headers.Add("Cache-Control", "public,max-age=6000");
            Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnActionExecuted{this.Order}");
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnActionExecuting{this.Order}");
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnResultExecuting{this.Order}");
        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine($"This {nameof(CustomActionCacheFilterAttribute)} OnResultExecuted{this.Order}");
        }
    }

ResourceFilter

public class CustomResourceFilterAttribute : Attribute, IResourceFilter, IFilterMetadata
    {
        private static Dictionary<string, IActionResult> CustomCache = new Dictionary<string, IActionResult>();
        /// <summary>
        /// 发生在其他动作之前
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuting");
            //if 有缓存,直接返回缓存
            string key = context.HttpContext.Request.Path;
            if (CustomCache.ContainsKey(key))
            {
                context.Result = CustomCache[key];//断路器--到Result生成了,但是Result还需要转换成Html
            }
        }
        /// <summary>
        /// 发生在其他动作之后
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuted");
            //这个应该缓存起来
            string key = context.HttpContext.Request.Path;
            if (!CustomCache.ContainsKey(key))
            {
                CustomCache.Add(key, context.Result);
            }
        }
    }

使用方式

注册全局

services.AddControllersWithViews(
            options =>
            {
                options.Filters.Add<CustomExceptionFilterAttribute>();//全局注册
                options.Filters.Add<CustomGlobalFilterAttribute>();
            });

第一种使用方式

[ServiceFilter(typeof(CustomExceptionFilterAttribute))]
public IActionResult Index()
{
    return View();
}
 public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped(typeof(CustomExceptionFilterAttribute));//不是直接new  而是容器生成 就可以自动注入了
}

第二种使用方式

[TypeFilter(typeof(CustomExceptionFilterAttribute))]
public IActionResult Index()
{
    return View();
}

第三种使用方式

 /// <summary>
    /// 基于完成Filter的依赖注入
    /// </summary>
    public class CustomIOCFilterFactoryAttribute : Attribute, IFilterFactory
    {
        private readonly Type _FilterType = null;

        public CustomIOCFilterFactoryAttribute(Type type)
        {
            this._FilterType = type;
        }
        public bool IsReusable => true;

        public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
        {
            //return (IFilterMetadata)serviceProvider.GetService(typeof(CustomExceptionFilterAttribute));

            return (IFilterMetadata)serviceProvider.GetService(this._FilterType);
        }
    }
[CustomIOCFilterFactoryAttribute(typeof(CustomExceptionFilterAttribute))]/
public IActionResult Index()
{
    return View();
}

执行顺序

/// <summary>
/// 全局---控制器---Action  Order默认0,从小到大执行  可以负数
 /// </summary>
 /// <returns></returns>
 [CustomActionFilterAttribute(Order = 10)]
 [CustomActionFilterAttribute]
 [CustomActionCacheFilterAttribute(Order = -1)]
 public IActionResult Info()
 {
     Console.WriteLine($"This is {nameof(ThirdController)} Info");

     base.ViewBag.Now = DateTime.Now;
     Thread.Sleep(2000);
     return View();
 }

Resource过滤器的使用缓存页面直接返回

[CustomResourceFilterAttribute]//缓存了变量
 public IActionResult Info()
 {
     Console.WriteLine($"This is {nameof(ThirdController)} Info");

     base.ViewBag.Now = DateTime.Now;
     Thread.Sleep(2000);
     return View();
 }