ASP.Net Core 5.0 MVC中AOP思想的體現(五種過濾器)並結合專案案例說明過濾器的用法

明志德道發表於2021-02-10

執行順序

 

 使用方法,首先實現各自的介面,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做資料快取的效果

 

 

 

相關文章