相信對權限過濾大家都不陌生,用戶要訪問一個頁面時,先對其權限進行判斷並進行相應的處理動作。
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方法
這時候看到了嗎?
要在一個action方法中使用一個過濾器
只要在該方法上貼一個過濾器的標簽就ok~
生成運行,結果如下:
但是,有時候我們會有這樣的一需求:
在過濾器中當遇到了貼了某某標簽的action方法就跳過不進行驗證
這怎么辦呢?
可以通過filterContext的ActionDescriptor屬性類完成這易操作
ActionDescriptor顧名思義,action方法的描述着
在ActionDescriptor中我們可以拿到相應的action方法信息,甚至還可以拿到一個控制器描述着ControllerDescriptor
代碼如下:
結果如圖:
可以看到,action方法中和OnActionExecuted中的Response.Write都沒有被執行,也就是說,該action方法被跳過了
之前我們使用的是IActionFilter接口中的方法
接下來介紹IResultFilter接口方法
IResultFilter中同樣也有兩個方法
我們將FilterTest改為下面代碼:
可以看到,IResultFilter接口中的方法和IActionFilter方法的區別就是執行位置不一樣
但是呢,mvc框架中還有一個過濾器
他就是權限過濾器AuthorizeAttribute
該過濾器在所有action方法過濾器之前執行,也就是說,提供了一個可以超前驗證的方法
我們在添加一個新的過濾器類,並繼承自AuthorizeAttribute
重寫其OnAuthorization方法如下:
這里需要注意,把基類的OnAuthorization方法去掉,因為我們並不需要,而且留着可能會出現一些錯誤異常
為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中