在.Net Framework MVC 中有四種過濾器,授權過濾器(Authorize)、Action 過濾器、結果過濾器(Result)、例外過濾器(Exception)四種過濾器,在.Net Core MVC中,有五種過濾器,授權過濾器、Action過濾器、例外過濾器、結果過濾器、資源過濾器,新增了資源過濾器,
.Net Core MVC和.Net Framework MVC在基本使用上差別不大,主要的還是框架的差別,其中路由是個很重要的東西,參考文章:https://www.cnblogs.com/durow/p/5992926.html

Action過濾器、結果過濾器、Exception,三個特性,沒有什么變化,在ExceptionFilter多了個Order引數,就是用來排序的,

結果過濾器,包裝了單個Action Result的執行,當且晉檔Action方法成功執行完畢后才運行,它們是理想的圍繞視圖執行或格式處理的邏輯(所在之處),繼承Attribute,IResultFilter
/// <summary> /// Result的Filter /// </summary> public class CustomResultFilterAttribute : Attribute, IResultFilter { //private Logger logger = Logger.CreateLogger(typeof(CustomResultFilterAttribute)); public void OnResultExecuted(ResultExecutedContext context) { Console.WriteLine("OnResultExecuted Executed!"); //logger.Info("OnResultExecuted Executed!"); } public void OnResultExecuting(ResultExecutingContext context) { Console.WriteLine("OnResultExecuting Executing!"); //logger.Info("OnResultExecuting Executing!"); } }
例外過濾器,為MVC隱藏程式為處理例外應用全域策略,繼承ExceptionFilterAttribute
/// <summary> /// 例外處理的Filter /// </summary> public class CustomExceptionFilterAttribute : ExceptionFilterAttribute { private readonly IHostingEnvironment _hostingEnvironment; private readonly IModelMetadataProvider _modelMetadataProvider; //private Logger logger = Logger.CreateLogger(typeof(CustomExceptionFilterAttribute)); /// <summary> /// IOC來的 /// </summary> /// <param name="hostingEnvironment"></param> /// <param name="modelMetadataProvider"></param> public CustomExceptionFilterAttribute( IHostingEnvironment hostingEnvironment, IModelMetadataProvider modelMetadataProvider) { _hostingEnvironment = hostingEnvironment; _modelMetadataProvider = modelMetadataProvider; } /// <summary> /// 沒有處理的例外,就會進來 /// </summary> /// <param name="filterContext"></param> public override void OnException(ExceptionContext filterContext) { if (!filterContext.ExceptionHandled)//例外有沒有被處理過 { string controllerName = (string)filterContext.RouteData.Values["controller"]; string actionName = (string)filterContext.RouteData.Values["action"]; string msgTemplate = "在執行 controller[{0}] 的 action[{1}] 時產生例外"; //logger.Error(string.Format(msgTemplate, controllerName, actionName), filterContext.Exception); if (this.IsAjaxRequest(filterContext.HttpContext.Request))//檢查請求頭 { filterContext.Result = new JsonResult( new { Result = false, PromptMsg = "系統出現例外,請聯系管理員", DebugMessage = filterContext.Exception.Message }//這個就是回傳的結果 ); } else { var result = new ViewResult { ViewName = "~/Views/Shared/Error.cshtml" }; result.ViewData = new ViewDataDictionary(_modelMetadataProvider, filterContext.ModelState); result.ViewData.Add("Exception", filterContext.Exception); filterContext.Result = result; } filterContext.ExceptionHandled = true; } } private bool IsAjaxRequest(HttpRequest request) { string header = request.Headers["X-Requested-With"]; return "XMLHttpRequest".Equals(header); } }View Code
定義完ExceptionFilter,該怎么注冊到全域呢?在Stratup.cs中ConfigureServer中,進行注冊
services.AddMvc(o => { o.Filters.Add(typeof(CustomExceptionFilterAttribute));// 這里就是全域注冊Filter }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
Action 過濾器,包裝了對單個Action方法的呼叫,可以將引數傳遞給Action并從中獲得Action Result,繼承IActionFilter
/// <summary> /// Action的Filter` /// </summary> public class CustomActionFilterAttribute : Attribute, IActionFilter { private ILogger<CustomActionFilterAttribute> _logger = null; public CustomActionFilterAttribute(ILogger<CustomActionFilterAttribute> logger) { this._logger = logger; } public void OnActionExecuted(ActionExecutedContext context) { //context.HttpContext.Response.WriteAsync("ActionFilter Executed!"); Console.WriteLine("ActionFilter Executed!"); //this._logger.LogDebug("ActionFilter Executed!"); } public void OnActionExecuting(ActionExecutingContext context) { //context.HttpContext.Response.WriteAsync("ActionFilter Executing!"); Console.WriteLine("ActionFilter Executing!"); //this._logger.LogDebug("ActionFilter Executing!"); } }
在Startup.cs中ConfigureServices進行注冊
//允許使用ServiceFilter 標記特性 services.AddScoped<CustomActionFilterAttribute>();
標記到Controller的ActionFilter
/// <summary> /// 標記到Controller /// </summary> public class CustomControllerActionFilterAttribute : Attribute, IActionFilter { private ILogger<CustomControllerActionFilterAttribute> _logger = null; public CustomControllerActionFilterAttribute(ILogger<CustomControllerActionFilterAttribute> logger) { this._logger = logger; } public void OnActionExecuted(ActionExecutedContext context) { //context.HttpContext.Response.WriteAsync("ActionFilter Executed!"); Console.WriteLine("ActionFilter Executed!"); //this._logger.LogDebug("ActionFilter Executed!"); } public void OnActionExecuting(ActionExecutingContext context) { //context.HttpContext.Response.WriteAsync("ActionFilter Executing!"); Console.WriteLine("ActionFilter Executing!"); //this._logger.LogDebug("ActionFilter Executing!"); } }
[TypeFilter(typeof(CustomControllerActionFilterAttribute),Order =-1)] public class ThirdController : Controller { }
注冊到全域的ActionFilter
public class CustomGlobalActionFilterAttribute : Attribute, IActionFilter { private ILogger<CustomGlobalActionFilterAttribute> _logger = null; public CustomGlobalActionFilterAttribute(ILogger<CustomGlobalActionFilterAttribute> logger) { this._logger = logger; } public void OnActionExecuted(ActionExecutedContext context) { //context.HttpContext.Response.WriteAsync("ActionFilter Executed!"); Console.WriteLine("ActionFilter Executed!"); //this._logger.LogDebug("ActionFilter Executed!"); } public void OnActionExecuting(ActionExecutingContext context) { //context.HttpContext.Response.WriteAsync("ActionFilter Executing!"); Console.WriteLine("ActionFilter Executing!"); //this._logger.LogDebug("ActionFilter Executing!"); } }
還是要在Startup中進行全域的注冊
services.AddMvc(o => { o.Filters.Add(typeof(CustomGlobalActionFilterAttribute));// 這里就是全域注冊Filter }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
分別對全域、控制器、Action注冊了ActionFilter默認執行順序:
全域OnActionExecuting===》控制器的OnActionExecuting====》Action的OnActionExecuting====》執行Action ====》Action的OnActionExecuted====》控制器的OnActionExecuted====》全域的OnActionExecuted,類似于一個俄羅斯套娃,也可以說是一個洋蔥模型,
資源過濾器,是授權之后第一個用來處理請求的過濾器,也是最后一個接觸到請求的過濾器(因為之后就會離開過濾器管道),在性能方面,資源過濾器在實作快取或短路過濾器管道尤其有用,繼承IResourceFilter
/// <summary> /// 自定義的資源Filter /// </summary> public class CustomResourceFilterAttribute : Attribute, IResourceFilter { private static readonly Dictionary<string, object> _Cache = new Dictionary<string, object>(); private string _cacheKey; /// <summary> /// 控制器實體化之前 /// </summary> /// <param name="context"></param> public void OnResourceExecuting(ResourceExecutingContext context) { _cacheKey = context.HttpContext.Request.Path.ToString(); if (_Cache.ContainsKey(_cacheKey)) { var cachedValue = https://www.cnblogs.com/taotaozhuanyong/p/_Cache[_cacheKey] as ViewResult; if (cachedValue != null) { context.Result = cachedValue; } } } /// <summary> /// 把請求都處理完的 /// </summary> /// <param name="context"></param> public void OnResourceExecuted(ResourceExecutedContext context) { if (!String.IsNullOrEmpty(_cacheKey) && !_Cache.ContainsKey(_cacheKey)) { var result = context.Result as ViewResult; if (result != null) { _Cache.Add(_cacheKey, result); } } } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/114302.html
標籤:.NET Core
