C# ASP.NET MVC中Filter過濾器的使用 通過注冊到Global.asax注冊為全局 過濾所有action


原文鏈接 https://blog.csdn.net/pan_junbiao/article/details/84523935

比如 ActionFilter中ActionExecutingContext filterContext可以拿到請求中的上下文。可以拿到請求action的名字controller的名字。和要請求的action 的上的標簽等。filterContext.Result 可以給響應復制。截斷請求,從而執行當前返回結果。

MVC Filter是典型的AOP(面向切面編程)應用,在ASP.NET MVC中的4個過濾器類型,如下:

過濾器類型 接口 默認實現 描述
Action IActionFilter ActionFilterAttribute 在動作方法之前及之后運行
Result IResultFilter ActionFilterAttribute 在動作結果被執行之前和之后運行
AuthorizationFilter IAuthorizationFilter AuthorizeAttribute 首先運行,在任何其它過濾器或動作方法之前
Exception IExceptionFilter HandleErrorAttribute 只在另一個過濾器、動作方法、動作結果彈出異常時運行

但是默認實現它們的過濾器只有三種,分別是ActionFilter(方法),Authorize(授權),HandleError(錯誤處理)。

1、Action過濾器

在ASP.NET MVC中創建MvcApp項目,創建文件夾Filter,然后新建類MyActionFilterAttribute(為了遵循默認的約定,名稱以Attribute結尾),繼承自ActionFilterAttribute類。ActionFilterAttribute類有如下4個方法。


   
   
   
           
  1. using System;
  2. namespace System.Web.Mvc
  3. {
  4. [ AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
  5. public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
  6. {
  7. protected ActionFilterAttribute();
  8. public virtual void OnActionExecuted(ActionExecutedContext filterContext);
  9. public virtual void OnActionExecuting(ActionExecutingContext filterContext);
  10. public virtual void OnResultExecuted(ResultExecutedContext filterContext);
  11. public virtual void OnResultExecuting(ResultExecutingContext filterContext);
  12. }
  13. }

實現MyActionFilterAttribute類:


   
   
   
           
  1. using System;
  2. using System.Web.Mvc;
  3. namespace MvcApp.Filter
  4. {
  5. public class MyActionFilterAttribute : ActionFilterAttribute
  6. {
  7. public override void OnActionExecuting(ActionExecutingContext filterContext)
  8. {
  9. //1、獲取請求的類名和方法名
  10. string strController = filterContext.RouteData.Values[ "controller"].ToString();
  11. string strAction = filterContext.RouteData.Values[ "action"].ToString();
  12. //2、用另一種方式獲取請求的類名和方法名
  13. string strController2 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
  14. string strAction2 = filterContext.ActionDescriptor.ActionName;
  15. filterContext.HttpContext.Response.Write( "控制器:" + strController + "<br/>");
  16. filterContext.HttpContext.Response.Write( "控制器:" + strController2 + "<br/>");
  17. filterContext.HttpContext.Response.Write( "Action:" + strAction + "<br/>");
  18. filterContext.HttpContext.Response.Write( "Action:" + strAction2 + "<br/>");
  19. filterContext.HttpContext.Response.Write( "Action執行前:" + DateTime.Now.ToString( "yyyy-MM-dd hh:mm:ss fff") + "<br/>");
  20. base.OnActionExecuting(filterContext);
  21. }
  22. public override void OnActionExecuted(ActionExecutedContext filterContext)
  23. {
  24. filterContext.HttpContext.Response.Write( "Action執行后:" + DateTime.Now.ToString( "yyyy-MM-dd hh:mm:ss fff") + "<br/>");
  25. base.OnActionExecuted(filterContext);
  26. }
  27. }
  28. }

對於過濾器,我們可以把它們加在3個地方,一個是控制器上面(控制器下面的所有Action),一個是Action上面(指定標識的Action),另一個就是全局位置(所有控制器中的Action)。這里只演示在Action上面和Home控制器中:


   
   
   
           
  1. [ MyActionFilter]
  2. public ActionResult Index()
  3. {
  4. return View();
  5. }

2、Result過濾器

新建MyResultFilterAttribute類,繼承ActionFilterAttribute:


   
   
   
           
  1. using System;
  2. using System.Web.Mvc;
  3. namespace MvcApp.Filter
  4. {
  5. public class MyResultFilterAttribute : ActionFilterAttribute
  6. {
  7. /// <summary>
  8. /// 加載“視圖”前執行
  9. /// </summary>
  10. /// <param name="filterContext"></param>
  11. public override void OnResultExecuting(ResultExecutingContext filterContext)
  12. {
  13. filterContext.HttpContext.Response.Write( "加載視圖前執行 OnResultExecuting" + DateTime.Now.ToString( "yyyy-MM-dd hh:mm:ss fff") + "<br/>");
  14. base.OnResultExecuting(filterContext);
  15. }
  16. /// <summary>
  17. /// 加載“視圖”后執行
  18. /// </summary>
  19. /// <param name="filterContext"></param>
  20. public override void OnResultExecuted(ResultExecutedContext filterContext)
  21. {
  22. filterContext.HttpContext.Response.Write( "加載視圖后執行 OnResultExecuted" + DateTime.Now.ToString( "yyyy-MM-dd hh:mm:ss fff") + "<br/>");
  23. base.OnResultExecuted(filterContext);
  24. }
  25. }
  26. }

這里把MyResultFilter過濾器加在控制器上面,相當於給Home控制器中的所有的Action方法添加了MyResultFilter過濾器。


   
   
   
           
  1. using MvcApp.Filter;
  2. using System.Web.Mvc;
  3. namespace MvcApp.Controllers
  4. {
  5. [ MyResultFilter]
  6. public class HomeController : Controller
  7. {
  8. [ MyActionFilter]
  9. public ActionResult Index()
  10. {
  11. return View();
  12. }
  13. }
  14. }

3、AuthorizeAttribute過濾器

創建MyAuthorizeAttribute類,繼承AuthorizeAttribute類:


   
   
   
           
  1. using System.Web.Mvc;
  2. namespace MvcApp.Filter
  3. {
  4. /// <summary>
  5. /// 授權過濾器
  6. /// </summary>
  7. public class MyAuthorizeAttribute : AuthorizeAttribute
  8. {
  9. public override void OnAuthorization(AuthorizationContext filterContext)
  10. {
  11. filterContext.HttpContext.Response.Write( "OnAuthorization<br/>");
  12. //注釋掉父類方法,因為父類里的OnAuthorization方法會調用ASP.NET的授權驗證機制
  13. //base.OnAuthorization(filterContext);
  14. }
  15. }
  16. }

在控制器Home中的Index上添加MyAuthorize過濾器:


   
   
   
           
  1. [ MyAuthorize]
  2. [ MyActionFilter]
  3. public ActionResult Index()
  4. {
  5. return View();
  6. }

通常Authorize過濾器也是在全局過濾器上面的,主要用來做登錄驗證或者權限驗證,在App_Start目錄下的FilterConfig類的RegisterGlobalFilters方法中添加:


   
   
   
           
  1. public class FilterConfig
  2. {
  3. public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  4. {
  5. //filters.Add(new HandleErrorAttribute());
  6. //添加全局授權過濾器
  7. filters.Add( new MyAuthorizeAttribute());
  8. }
  9. }

在全局中注冊過濾器,則所有控制器的所有行為(Action)都會執行這個過濾器。

運行結果,如下圖:

4、Exception過濾器

創建MyHandleErrorAttribute類,繼承HandleErrorAttribute類:


   
   
   
           
  1. using System;
  2. using System.Web.Mvc;
  3. namespace MvcApp.Filter
  4. {
  5. /// <summary>
  6. /// 異常處理過濾器
  7. /// </summary>
  8. public class MyHandleErrorAttribute : HandleErrorAttribute
  9. {
  10. public override void OnException(ExceptionContext filterContext)
  11. {
  12. //1、獲取異常對象
  13. Exception ex = filterContext.Exception;
  14. //2、記錄異常日志
  15. //3、重定向友好頁面
  16. filterContext.Result = new RedirectResult( "~/error.html");
  17. //4、標記異常已經處理完畢
  18. filterContext.ExceptionHandled = true;
  19. base.OnException(filterContext);
  20. }
  21. }
  22. }

在Action上面添加MyHandleError過濾器:


   
   
   
           
  1. [ MyHandleError]
  2. public ActionResult GetErr()
  3. {
  4. int a = 0;
  5. int b = 1 / a;
  6. return View();
  7. }

創建異常錯誤友好提示頁面error.html。


   
   
   
           
  1. <body>
  2. 自定義錯誤頁面
  3. </body>

運行會自動跳轉到error.html頁面。

如果頁面沒有跳轉,就需要去Web.config配置文件中的<system.web>節點下面添加如下配置節點,開啟自定義錯誤:

<customErrors mode="On"></customErrors>
  
  
  
          

通常這樣的異常處理是放在全局過濾器上面的,只要任意Action方法報錯就會執行MyHandleError過濾器中的代碼。

修改App_Start目錄下面的FilterConfig類:


   
   
   
           
  1. public class FilterConfig
  2. {
  3. public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  4. {
  5. //filters.Add(new HandleErrorAttribute());
  6. //添加全局授權過濾器
  7. filters.Add( new MyAuthorizeAttribute());
  8. //添加全局異常處理過濾器
  9. filters.Add( new MyHandleErrorAttribute());
  10. }
  11. }

Global.asax下的代碼:


   
   
   
           
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using System.Web.Optimization;
  7. using System.Web.Routing;
  8. namespace MvcApp
  9. {
  10. public class MvcApplication : System. Web. HttpApplication
  11. {
  12. protected void Application_Start()
  13. {
  14. AreaRegistration.RegisterAllAreas();
  15. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  16. RouteConfig.RegisterRoutes(RouteTable.Routes);
  17. BundleConfig.RegisterBundles(BundleTable.Bundles);
  18. }
  19. }
  20. }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM