ASP.NET MVC/フィルター
ASP.NET MVCのフィルターとは、コントローラークラスやアクションメソッド(コントローラークラスのメソッド)に、属性(Attribute)もちいて処理を挿入する機能のことである。
たとえばユーザー認証処理がされている、されていない、などの処理をアクションごとに書いていたのでは面倒、かつ本流ではないソースコードが入りまくり見通しが悪くなるのでフィルター化しておくと便利だという。
目次
使い道の例
たとえばEditアクションはログインしているユーザーのみとする場合は以下のようになる。
[Authorize]
public ActionResult Edit(int id)
{
//...
return View();
}
ASP.NET MVCでは上記のAuthorize属性をはじめ、OutputCache属性やChildActionOnly属性、HandleError属性など、さまざまなフィルターがあらかじめ用意されている。またフィルターは自作することも可能である。
フィルターの種類
ASP.NET MVCのフィルターは大きく、承認フィルター、アクションフィルター、結果フィルター、例外フィルターの4つに分けられる。
承認フィルター
IAuthorizationFilterインターフェイスを実装し、認証に関わる処理を記述する。
アクションフィルター
IActionFilterインターフェイスを実装し、アクションメソッドの実行前後で行われるべき処理を記述する。
結果フィルター
IResultFilterインターフェイスを実装し、ActionResultの実行前後(ビューエンジンの実行前後)に行われるべき処理を記述する。
例外フィルター
IExceptionFilterインターフェイスを実装し、例外発生時に行われるべき処理を記述する。
フィルターの実行順序
承認フィルター ↓ アクションフィルター前処理 ↓ アクションメソッド ↓ アクションフィルター後処理 ↓ 結果フィルター前処理 ↓ ビューエンジン ↓ 結果フィルター後処理 その他:例外フィルター
標準フィルター
ASP.NET MVCにはあらかじめいくつかフィルターが用意されている。なお、MSDNのドキュメントでは「実装例」と繰り返し書かれてる。
- AuthorizeAttribute - 承認フィルター
- OutputCacheAttribute - 結果フィルター
- HandleErrorAttribute - 例外フィルター
独自フィルター
自前の独自フィルターを作成するには、基本的にFilterAttributeクラスを継承し、前述のフィルターの種類に応じたインターフェイスを実装する。
たとえば標準フィルターのAuthorizeAttributeであれば以下のようになっている。
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute
: FilterAttribute, // FilterAttributeを継承して
IAuthorizationFilter // IAuthorizationFilterを実装する
{
//...
}
なお、一般的なアクションフィルターであればActionFilterAttributeクラスという便利クラスもあるので、そちらを継承して使った方が手っ取り早い。
public class LoggingFilterAttribute : ActionFilterAttribute
{
// アクションフィルター前処理
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Trace.Write("(Logging Filter)Action Executing: " +
filterContext.ActionDescriptor.ActionName);
base.OnActionExecuting(filterContext);
}
// アクションフィルター後処理
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception != null)
filterContext.HttpContext.Trace.Write("(Logging Filter)Exception thrown");
base.OnActionExecuted(filterContext);
}
}