?? 前言
我們知道 ASP.NET Web API 過濾器,也是屬于消息處理機制中的一部分。正因如此,我們經常使用它來完成對請求的授權驗證、參數驗證,以及請求的 Log 記錄,程序異常捕獲等。
?
1.?? 常用的四大過濾器
?? ASP.NET Web API 2 中的所有過濾器位于 System.Web.Http.dll 中的 System.Web.Http.Filters 命名空間中,繼承關系如下:
1.?? AuthenticationFilter:身份證驗證過濾器,必須實現 IAuthenticationFilter 接口。微軟推出了一套身份驗證組件(ASP.NET Identity)就是采用了該過濾實現,該組件位于 System.Web.Http.Owin.dll 程序集,主要使用 System.Web.Http.HostAuthenticationFilter 過濾器,可參考:https://www.cnblogs.com/yidianfeng/p/7765984.html
2.?? AuthorizationFilter:授權過濾器,必須繼承于 AuthorizationFilterAttribute 類,或實現 IAuthorizationFilter 接口。
3.?? ActionFilter:動作過濾器,必須繼承于 ActionFilterAttribute 類,或者實現 IActionFilter 接口。
4.?? ExceptionFilter:異常過濾器,必須繼承于 ExceptionFilterAttribute 類,或者實現 IExceptionFilter 接口。
?
?? 注意:因為 Web API 與 MVC 中很多過濾器名稱都相同,但過濾器位于的程序集和命名空間是不同的。MVC 中的過濾器位于 System.Web.Mvc.dll 中的 System.Web.Mvc 命名空間,這不能搞混了!
?
?? 首先,我們來看下過濾器的執行順序
1)?? 圖中描述了4種過濾器的執行順序,而每個執行過程中發生異常,都會被異常過濾器捕獲。
2)?? 每當一個請求“進來”時,可能存在的三種響應結果:401,無訪問權限,500,請求發生異常,200,請求成功。
?
?? 過濾器的用法
1)?? 創建過濾器
1.?? AuthenticationFilter(身份驗證過濾器)
它是最先執行的過濾器,一般用于對訪問者的身份認證等。
/// <summary>
/// 身份驗證過濾器特性。
/// </summary>
public class CustomAuthenticationFilterAttribute
??? : System.Web.Http.Filters.FilterAttribute, System.Web.Http.Filters.IAuthenticationFilter
{
??? public System.Threading.Tasks.Task AuthenticateAsync(System.Web.Http.Filters.HttpAuthenticationContext context, System.Threading.CancellationToken cancellationToken)
??? {
??????? //這里完成身份驗證...
??????? return Task.FromResult(0);
??? }
?
??? public System.Threading.Tasks.Task ChallengeAsync(System.Web.Http.Filters.HttpAuthenticationChallengeContext context, System.Threading.CancellationToken cancellationToken)
??? {
??????? return Task.FromResult(0);
??? }
}
?
2.?? AuthorizationFilter(授權過濾器)
授權過濾器通常用于控制接口訪問權限,只有當訪問權限滿足時,才允許訪問程序中的接口。用于提高程序的安全性,防止程序被惡意篡改。通常可以使用 Basic 認證、簽名認證等。
/// <summary>
/// 授權過濾器特性。
/// </summary>
public class CustomAuthorizationFilterAttribute : System.Web.Http.Filters.AuthorizationFilterAttribute
{
??? /// <summary>
??? /// 在過程請求授權時調用。
??? /// </summary>
??? /// <param name="actionContext">操作上下文,它封裝有關使用 System.Web.Http.Filters.AuthorizationFilterAttribute 的信息。</param>
??? public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
??? {
??????? //這里完成請求權限的控制...
??? }
}
?
3.?? ActionFilter(動作過濾器)
動作過濾器中有兩個方法,一個是 OnActionExecuting(),在調用 Action() 方法之前執行,另一個是 OnActionExecuted(),在調用 Action() 方法之后執行。
/// <summary>
/// 動作過濾器特性。
/// </summary>
public class CustomActionFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
??? /// <summary>
??? /// 在調用操作方法之前發生。
??? /// </summary>
??? /// <param name="actionContext">操作上下文。</param>
??? public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
??? {
??????? //這里完成請求參數的驗證...
??? }
?
??? /// <summary>
??? /// 在調用操作方法之后發生。
??? /// </summary>
??? /// <param name="actionExecutedContext">操作執行的上下文。</param>
??? public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
??? {
??????? //這里完成請求日志的記錄...
??? }
}
1.?? OnActionExecuting () 方法
通常可以在該方法中,完成對接口參數的效驗。
2.?? OnActionExecuted () 方法
一般可以用于記錄調用接口的 log。
?
4.?? ExceptionFilter(異常過濾器)
異常過濾器中一個 OnException() 方法,當程序發生異常時將被執行。通常可以用于監控程序異常,記錄異常日志。
/// <summary>
/// 自定義異常過濾器特性。
/// </summary>
public class CustomExceptionFilterAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
{
??? /// <summary>
??? /// 異常過濾器特性。
??? /// </summary>
??? /// <param name="actionExecutedContext">操作的上下文。</param>
??? public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
??? {
??????? //當程序發生異常時執行的代碼...
??????? actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(
??????????? System.Net.HttpStatusCode.InternalServerError,
??????????? string.Format("異常:【{0}】已被捕獲", actionExecutedContext.Exception.Message));
??? }
}
?
2)?? 注冊過濾器
1.?? 注冊全局過濾器
在 WebApiConfig 類的 Register() 方法中注冊,例如:
config.Filters.Add(new WebAPI2.Filter.Filters.CustomExceptionFilterAttribute());
config.Filters.Add(new WebAPI2.Filter.Filters.CustomActionFilterAttribute());???????????
config.Filters.Add(new WebAPI2.Filter.Filters.CustomAuthorizationFilterAttribute());
config.Filters.Add(new WebAPI2.Filter.Filters.CustomAuthenticationFilterAttribute());??
通常異常過濾、動作過濾器都是定義為全局過濾器。
?
2.?? 定義 Controller 或 Action 過濾器
我們需要為指定的 Controller 或 Action 單獨設置過濾器時,也可以這樣定義:
[WebAPI2.Filter.Filters.CustomActionFilter]
[WebAPI2.Filter.Filters.CustomAuthorizationFilter]
[RoutePrefix("api/values")]
public class ValuesController : ApiController
{ }
或者
[WebAPI2.Filter.Filters.CustomAuthorizationFilter]
public HttpResponseMessage Get(HttpRequestMessage request, int id)
{
return request.CreateResponse<string>(HttpStatusCode.OK, "Get Action 方法執行,id值為:" + id);
}
?
?? 注意:過濾器不能在 FilterConfig 中的 RegisterGlobalFilters() 去注冊,因為這里是注冊 MVC 過濾器的。