什么是過濾器?
MVC中的每一個(gè)請(qǐng)求,都會(huì)分配給相應(yīng)的控制器(Controller)和對(duì)應(yīng)的行為方法(Action)去處理,那么如果我們想要在Action處理的前后加上一些額外的處理邏輯怎么辦呢?這時(shí)候就用到了過濾器(Filters)。
在ASP.NET MVC的請(qǐng)求處理過程中有19個(gè)管道事件,這些事件分布在請(qǐng)求處理的各個(gè)節(jié)點(diǎn)中,比如BeginRequest(開始處理請(qǐng)求時(shí)觸發(fā))、AuthenticateRequest(對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證時(shí)觸發(fā))、AuthorizeRequest(對(duì)請(qǐng)求進(jìn)程授權(quán)時(shí)觸發(fā))…等等等等。而過濾器的主要作用就是將我們的附加邏輯注入到這些請(qǐng)求處理管道中。
在實(shí)際業(yè)務(wù)中,在Action方法前后添加額外附加邏輯的情況有很多,過濾器就是用來完成此功能。通過過濾器可以將與業(yè)務(wù)邏輯無關(guān)但經(jīng)常需要執(zhí)行的代碼分離開,使我們的代碼邏輯性更加清晰,代碼更加簡(jiǎn)潔。
過濾器的類型與作用
MVC給我們提供了四種過濾器,基本滿足了我們實(shí)際業(yè)務(wù)中常用的需求,包括以下:
類型名稱 | 實(shí)現(xiàn)的接口 | 默認(rèn)的實(shí)現(xiàn)類 | 作用 |
---|---|---|---|
授權(quán)過濾器 | IAuthorizationFilter | AuthorizeAttribute | 用于限制進(jìn)入控制器或控制器的某個(gè)行為方法 |
動(dòng)作過濾器 | IActionFilter | ActionFilterAttribute | 用于進(jìn)入動(dòng)作方法之前或之后的處理 |
結(jié)果過濾器 | IResultFilter | ActionFilterAttribute | 用于動(dòng)作方法返回結(jié)果之前或之后的處理 |
異常處理過濾器 | IExceptionFilter | HandleErrorAttribute | 用于處理某個(gè)動(dòng)作方法或某個(gè)控制器里面拋出的異常 |
這四種類型的接口是MVC對(duì)過濾器的一個(gè)接口規(guī)范,同時(shí)MVC默認(rèn)通過AuthorizeAttribute(授權(quán))、HandleErrorAttribute(異常處理)、ActionFilterAttribute(動(dòng)作和結(jié)果)三個(gè)類實(shí)現(xiàn)了這四個(gè)接口。
需要注意的是ActionFilterAttribute類既實(shí)現(xiàn)了IActionFilter接口,也實(shí)現(xiàn)了IResultFilter接口。這是個(gè)抽象類,要求必須提供一個(gè)實(shí)現(xiàn),AuthorizeAttribute和HandleErrorAttribute類則包含了一些有用的特性,可以不必創(chuàng)建派生類進(jìn)行使用。所以我們一般都會(huì)通過繼承ActionFilterAttribute類,實(shí)現(xiàn)自定義的過濾器。
除以上接口之外,我們還要用到FilterAttribute類,這個(gè)類將我們的過濾器包裝成了特性,使我們的過濾器可以方便的在Action方法上方使用。
定義過濾器
過濾器有以下幾個(gè)特點(diǎn):
- 可用于動(dòng)作方法(Action)
- 可用于控制器(Controller)
- 可多個(gè)Filter可同時(shí)使用
- 不同級(jí)別可以混搭
- 可運(yùn)用于基類的過濾器,會(huì)影響該基類的所有派生類
下面我們逐一介紹下基本過濾器的使用方法。
授權(quán)過濾器
所有實(shí)現(xiàn)了IAuthorizationFilter接口的都可以稱之為授權(quán)過濾器。它的接口定義如下:
namespace System.Web.Mvc
{
//
// 摘要:
// 定義授權(quán)篩選器所需的方法。
public interface IAuthorizationFilter
{
//
// 摘要:
// 在需要授權(quán)時(shí)調(diào)用。
//
// 參數(shù):
// filterContext:
// 篩選器上下文。
void OnAuthorization(AuthorizationContext filterContext);
}
}
授權(quán)過濾器是最先運(yùn)行的過濾器,它運(yùn)行在其它過濾器和Action方法之前??蛻舳苏?qǐng)求在調(diào)用Action之前,MVC框架會(huì)檢測(cè)Action上是否有授權(quán)過濾器,如果有會(huì)調(diào)用OnAuthorization方法,如果此方法批準(zhǔn)了請(qǐng)求,才會(huì)調(diào)用相應(yīng)的Action。流程如圖:
MVC默認(rèn)使用AuthorizeAttribute實(shí)現(xiàn)了IAuthorizationFilter接口,所以我們可以在Action方法上直接添加Authorize特性標(biāo)簽來驗(yàn)證授權(quán):
打開Index頁面,會(huì)顯示無權(quán)限:
由于使用的是MVC自帶的授權(quán)驗(yàn)證方法,未能符合它的驗(yàn)證機(jī)制,所以無權(quán)限查看。通常我們需要添加一個(gè)新的派生自AuthorizeAttribute類的授權(quán)過濾器來完成我們自己業(yè)務(wù)邏輯。
下面我們自定義一個(gè)授權(quán)過濾器。我們?cè)贛VC項(xiàng)目中添加一個(gè)Filters文件夾,我們所有自定義的過濾器都放可以到這個(gè)文件夾下,便于管理。
在Filters下創(chuàng)建一個(gè)類,類名為MyAuthorizeAttribute。需要注意,過濾器要以Attribute結(jié)尾,這是MVC的約定。代碼如下:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
//重寫授權(quán)檢查方法,返回值為true,允許訪問,false,禁止訪問。
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//請(qǐng)求參數(shù)user為空,禁止訪問
if (string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["user"]))
{
return false;
}
return true;
}
}
可以看到,我們只要重寫AuthorizeCore方法就可以根據(jù)我們的業(yè)務(wù)需求判斷是否有權(quán)限訪問,返回值為true允許訪問,返回值為false禁止訪問。
回到HomeController,我們給About方法加上我們自定義的特性:
我們看看效果:
可以看到,當(dāng)About頁面沒有user參數(shù)時(shí),會(huì)提示無權(quán)限,有user參數(shù)則可以訪問通過。
在實(shí)際業(yè)務(wù)中我們可以使用授權(quán)過濾器來管理用戶登錄狀態(tài)的授權(quán)驗(yàn)證。當(dāng)然,我的這個(gè)例子只是基礎(chǔ)的用法,實(shí)際業(yè)務(wù)比這復(fù)雜的多,那么就需要我們自己去思考設(shè)計(jì)授權(quán)過濾器方法了。
動(dòng)作過濾器
動(dòng)作過濾器需要實(shí)現(xiàn)IActionFilter接口,接口定義如下:
//
// 摘要:
// 定義操作篩選器中使用的方法。
public interface IActionFilter
{
//
// 摘要:
// 在執(zhí)行操作方法后調(diào)用。
//
// 參數(shù):
// filterContext:
// 篩選器上下文。
void OnActionExecuted(ActionExecutedContext filterContext);
//
// 摘要:
// 在執(zhí)行操作方法之前調(diào)用。
//
// 參數(shù):
// filterContext:
// 篩選器上下文。
void OnActionExecuting(ActionExecutingContext filterContext);
}
我們看到該接口里有兩個(gè)方法OnActionExecuting和OnActionExecuted,前者在動(dòng)作方法執(zhí)行前調(diào)用,后者在動(dòng)作方法執(zhí)行后調(diào)用。
OnActionExecuting方法是在Action方法執(zhí)行前調(diào)用的,那么我們可以利用這個(gè)方法來檢測(cè)請(qǐng)求,并且可以在這里修改請(qǐng)求,取消請(qǐng)求等等操作。
客戶端的請(qǐng)求信息是一個(gè)ActionExecutingContext對(duì)象,它繼承自ControllerContext類,屬性如下:
名稱 | 類型 | 說明 |
---|---|---|
ActionDescriptor | ActionDescriptor | 獲取或設(shè)置操作描述符。 |
ActionParameters | IDictionary | 獲取或設(shè)置操作方法參數(shù)。 |
Result | ActionResult | 獲取或設(shè)置由操作方法返回的結(jié)果。 |
我們添加一個(gè)自定義的Action過濾器。由于ActionFilterAttribute類實(shí)現(xiàn)了IActionFilter接口,所以我們直接繼承ActionFilterAttribute類即可,并且重寫OnActionExecuting和OnActionExecuted方法。如下:
public class MyActionAttribute : ActionFilterAttribute
{
///
/// Action調(diào)用之前運(yùn)行
///
///
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (string.Equals(filterContext.HttpContext.Request.HttpMethod, "get", StringComparison.CurrentCultureIgnoreCase))
{
filterContext.Result = new HttpNotFoundResult("只允許POST請(qǐng)求!");
}
}
///
/// Action調(diào)用之后運(yùn)行
///
///
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
我們給Index方法添加上MyAction特性標(biāo)簽:
打開Index頁,顯示如下:
可以看到,頁面返回了404錯(cuò)誤,提示信息為我們?cè)O(shè)置的Message。
-
Controller
+關(guān)注
關(guān)注
0文章
398瀏覽量
57600 -
Asp.net
+關(guān)注
關(guān)注
0文章
36瀏覽量
14082 -
過濾器
+關(guān)注
關(guān)注
1文章
439瀏覽量
20371 -
MVC
+關(guān)注
關(guān)注
0文章
73瀏覽量
14127
發(fā)布評(píng)論請(qǐng)先 登錄
ASP.net Ajax開發(fā).zip
《ASP.net Ajax開發(fā)》初識(shí)ASP.NET AJAX.pdf
北大青鳥asp.net教程
Programming Microsoft ASP.NET

Asp.net中文手冊(cè)(CHM格式)
ASP.NET課程設(shè)計(jì)案例精編

Asp.net MVC框架自定義視圖引擎的實(shí)現(xiàn)
《ASP.NET 2.0網(wǎng)絡(luò)開發(fā)技術(shù)》 ASP.NET 2.0核
《ASP.NET 2.0網(wǎng)絡(luò)開發(fā)技術(shù)》 走進(jìn)ASP.NET 2.
《ASP.net Ajax開發(fā)》初識(shí)ASP.NET AJAX
過濾器的作用
ASP.NET MVC5教學(xué)之過濾器(下)

評(píng)論