執行順序
使用方法,首先實現各自的介面,override裡面的方法, 然後在startup 類的 ConfigureServices 方法,註冊它們。
services.AddTransient(typeof(MyAction)); services.AddTransient(typeof(MyResult)); services.AddTransient(typeof(MyException)); services.AddTransient(typeof(MyAuthorize)); services.AddTransient(typeof(MyResource)); services.AddTransient(typeof(CheckLogin));
下面我將程式碼貼出來,照著模仿就可以了
IActionFilter
public class MyAction :Attribute,IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; Console.WriteLine($"行為過濾器OnActionExecuted作用於{controllerName }控制器下的{actionName }方法執行之後</br>", Encoding.Default); } public void OnActionExecuting(ActionExecutingContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; Console.WriteLine($"行為過濾器OnActionExecuting作用於{controllerName }控制器下的{actionName }方法執行之前</br>", Encoding.UTF8); } }
IResultFilter
public class MyResult : Attribute,IResultFilter { public void OnResultExecuted(ResultExecutedContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; Console.WriteLine($"結果過濾器ResultExecuted作用於{controllerName }控制器下的{actionName }方法執行之後</br>", Encoding.Unicode); } public void OnResultExecuting(ResultExecutingContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; Console.WriteLine($"結果過濾器OnResultExecuting作用於{controllerName }控制器下的{actionName }方法執行之前</br>", Encoding.ASCII); } }
IExceptionFilter
public class MyException : Attribute,IExceptionFilter { public void OnException(ExceptionContext context) { ////呼叫框架本身異常處理器的方法 //base.OnException(filterContext); var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; //獲取異常資訊(可以根據實際需要寫到本地或資料庫中) var errorMsg = context.Exception.Message; Console.WriteLine($"異常過濾器OnException作用於{controllerName }控制器下的{actionName }方法發生了錯誤: {errorMsg}</br>"); //跳轉指定的錯誤頁面 context.ExceptionHandled = true; } }
IAuthorizationFilter
public class MyAuthorize : Attribute,IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; Console.WriteLine($"身份驗證過濾器OnAuthorization作用於{controllerName }控制器下的{actionName }方法</br>"); } }
IResourceFilter
public class MyResource : Attribute, IResourceFilter { private static Dictionary<string, object> CacheDictionary = new Dictionary<string, object>(); public void OnResourceExecuted(ResourceExecutedContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; //程式碼執行到這裡,就表示一定完成了邏輯計算;就有結果; string key = context.HttpContext.Request.Path; CacheDictionary[key] = context.Result; Console.WriteLine($"資源過濾器OnResourceExecuted 在{controllerName }控制器下的{actionName }方法執行之後,將結果資料快取起來</br>"); } public void OnResourceExecuting(ResourceExecutingContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; ///1.先判斷快取中是否有資料 ///2.如果有資料,就直接拿著資料走了 ///3.沒有就繼續往後,就去例項化控制器,去執行Action做計算 //快取:需要一個key; 只要是key不變,拿到的資料就不變; //如果做快取,一般請求路徑不變,資料一般不變; string key = context.HttpContext.Request.Path; if (CacheDictionary.Any(item => item.Key == key)) { Console.WriteLine($"資源過濾器OnResultExecuting 在{controllerName }控制器下的{actionName }方法執行之前 判斷有快取資料,直接返回資料</br>"); context.Result = CacheDictionary[key] as IActionResult; } //如果沒有快取---就繼續往後; Console.WriteLine($"資源過濾器OnResultExecuting 在{controllerName }控制器下的{actionName }方法執行之前 判斷沒有快取資料</br>"); } }
效果驗證
執行順序
發生異常時的順序
IResourceFilter做資料快取的效果