Asp.Net MVC Filter權限過濾使用說明


相信對權限過濾大家都不陌生,用戶要訪問一個頁面時,先對其權限進行判斷並進行相應的處理動作。

mvc中是如何實現權限驗證的?

mvc中是根據路由配置來請求控制器類中的一個方法

在mvc框架中為程序員提供了一種過濾器機制

通過過濾器,我們可以隨心所欲的控制訪問權限

 

首先,我們可以自己添加一個過濾器

添加一個類,名為MyFilter1Attribute

並繼承自ActionFilterAttribute類(注意,這里的ActionFilterAttribute的命名空間是System.Web.Mvc不要引用錯了~)

現在這個MyFilter1Attribute就是一個過濾器類了

因為繼承自ActionFilterAttribute類

所以我們自己添加的MyFilter1Attribute就擁有了許多過濾方法

我們對ActionFilterAttributeF12轉到定義看一看里面有什么東西

可以看到,這個ActionFilterAttribute是一個特性類(這就是人家為什么以Attribute結尾啦~)

並且實現了兩個很重要的接口IActionFilter,IResultFilter

我們在轉到定義看一下這兩個接口中有什么

可以看到

這兩個接口中各自定義了兩個方法,而ActionFilterAttribute既然實現了它們,那么ActionFilterAttribute自然也會擁有這四個方法

那么這四個方法是什么呢?

前面我們說到過,ActionFilterAttribute其實是一個特性類

什么是特性類?

就比如實體驗證的時候,為實體的字段貼上的標簽Required,還有HttpPost、HttpGet等標簽

而我們自己添加的MyFilter1Attribute也是一個特性類

這有什么用嗎?

等下你就知道了~

現在先在MyFilter1Attribute中重寫OnActionExecuting方法

其實我們可以從這個方法的名字上大概推出這個方法是做什么的了

沒錯,該方法會在action方法執行之前調用

反之IActionFilter中的另一個方法--OnActionExecuted就是在action方法執行完畢之后調用

public class MyFilter1Attribute:ActionFilterAttribute  
    {  
        //該方法會在action方法執行之前調用  
        public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法調用錢執行<br/>"); base.OnActionExecuting(filterContext); } //該方法會在action方法執行之后調用 public override void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在action方法調用后執行<br/>"); base.OnActionExecuted(filterContext); } } 

 

在Home控制器中添加一個action方法

[MyFilter1]  
public void FilterTest() { Response.Write("我是action方法,在這里執行了~~</br>"); } 

 

這時候看到了嗎?

要在一個action方法中使用一個過濾器

只要在該方法上貼一個過濾器的標簽就ok~ 
生成運行,結果如下:

但是,有時候我們會有這樣的一需求:

在過濾器中當遇到了貼了某某標簽的action方法就跳過不進行驗證

這怎么辦呢?

可以通過filterContext的ActionDescriptor屬性類完成這易操作

ActionDescriptor顧名思義,action方法的描述着

在ActionDescriptor中我們可以拿到相應的action方法信息,甚至還可以拿到一個控制器描述着ControllerDescriptor

代碼如下:

//該方法會在action方法執行之前調用  
        public override void OnActionExecuting(ActionExecutingContext filterContext)  
        {  
            filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法調用前執行<br/>"); //判斷該action方法時候有貼上MyFilter1Attribute標簽 if (filterContext.ActionDescriptor.IsDefined(typeof (MyFilter1Attribute),false)) { //如果有,為該action方法直接返回ContentResult,則該action方法在這里就有了返回值,相當於在這里就結束了,不會在去執行之后的方法,如:OnActionExecuted等 filterContext.Result = new ContentResult(); } base.OnActionExecuting(filterContext); } 

 

結果如圖:

 

可以看到,action方法中和OnActionExecuted中的Response.Write都沒有被執行,也就是說,該action方法被跳過了

 

之前我們使用的是IActionFilter接口中的方法

接下來介紹IResultFilter接口方法

 
//在action方法返回結果之后執行  
        public override void OnResultExecuting(ResultExecutingContext filterContext)  
        {  
            filterContext.HttpContext.Response.Write("我是OnActionExecuting,我action方法返回結果之前執行<br/>"); base.OnResultExecuting(filterContext); } //在action方法返回結果之前前執行 public override void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Write("我是OnResultExecuted,我在action方法返回結果之后執行<br/>"); base.OnResultExecuted(filterContext); } 

 

IResultFilter中同樣也有兩個方法

我們將FilterTest改為下面代碼:

[MyFilter1]  
        public ActionResult FilterTest() { Response.Write("我是action方法的Response.Write,在這里執行了~~</br>"); return View(); } 

並添加視圖如下:

<body>  
    <div>  
        我是FilterTest的視圖,在這里執行action方法~~  
    </div>  
</body>  

生成並運行,結果圖:

  

可以看到,IResultFilter接口中的方法和IActionFilter方法的區別就是執行位置不一樣

但是呢,mvc框架中還有一個過濾器

他就是權限過濾器AuthorizeAttribute

該過濾器在所有action方法過濾器之前執行,也就是說,提供了一個可以超前驗證的方法

我們在添加一個新的過濾器類,並繼承自AuthorizeAttribute

重寫其OnAuthorization方法如下:

這里需要注意,把基類的OnAuthorization方法去掉,因為我們並不需要,而且留着可能會出現一些錯誤異常

public class MyFilter2Attribute:AuthorizeAttribute  
    {  
        //在所有action方法過濾器之前執行  
        public override void OnAuthorization(AuthorizationContext filterContext) { filterContext.HttpContext.Response.Write("我是OnAuthorization,在所有action方法過濾器之前執行<br/>"); //base.OnAuthorization(filterContext);  } } 

action代碼

[MyFilter1]  
        [MyFilter2]  
        public ActionResult FilterTest() { Response.Write("我是action方法的Response.Write,在這里執行了~~</br>"); return View(); } 

 

 

為FilterTest方法在貼上MyFilter2標簽

運行:

 

有圖有證據~

如此一來

我們就可以根據需要選擇合適的方法進行權限驗證

但是這時候又有問題了

什么問題呢?

這個特性是貼在action方法上面的

如果我控制器中所有的action方法都要進行驗證怎么辦?

難道每個action方法都貼一遍嗎?

如果我程序中的所有控制器中的所有action方法都需要驗證呢?

放心~

懶惰的程序員們是不會去做這種傻事的~

如果一個控制器中的所有方法都需要驗證

那么我們可以再控制器類上統一貼上標簽,如下:

這樣一來該控制器中的所有action方法都會進行驗證

那么如果每個控制器類都要驗證呢?

這個時候我們就需要打開App_Start文件夾了

看到一個FilterConfig類了嗎

雙擊打開FilterConfig.cs

我們可以再這里進行添加全局的過濾器,比如:

 

最后我們在介紹一個異常處理的過濾器

添加一個過濾器類,並繼承自HandleErrorAttribute

public class MyFilter3Attribute:HandleErrorAttribute  
   {  
       //在程序中任何地方出現異常都會執行  
       public override void OnException(ExceptionContext filterContext) { //獲取異常對象 Exception ex = filterContext.Exception; //記錄錯誤日志 //導向友好錯誤界面 filterContext.Result = new RedirectResult("/Home/Index"); //重要!!告訴系統異常已處理!!如果沒有這個步驟,系統還是會按照正常的異常處理流程走 filterContext.ExceptionHandled = true; //base.OnException(filterContext);  } } 

 

 

注意,這里基類的OnException也是不需要的

異常處理的過濾器要放在全局/App_Start/FilterConfig.cs中

filters.Add(new MyFilter3Attribute());  

ok,搞定~


免責聲明!

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



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