asp.net-mvc
アクションフィルタ
サーチ…
ロギングアクションフィルタ
public class LogActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
Log("OnResultExecuting", filterContext.RouteData);
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
Log("OnResultExecuted", filterContext.RouteData);
}
private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
Debug.WriteLine(message, "Action Filter Log");
}
}
セッション制御アクションフィルタ - ページ&ajaxリクエスト
通常、認証および認可プロセスは、.net MVCの組み込みCookieおよびトークンのサポートによって実行されます。しかし、 Session
それを自分で行うことに決めた場合は、以下のロジックをページ要求とajax要求の両方に使用できます。
public class SessionControl : ActionFilterAttribute
{
public override void OnActionExecuting ( ActionExecutingContext filterContext )
{
var session = filterContext.HttpContext.Session;
/// user is logged in (the "loggedIn" should be set in Login action upon a successful login request)
if ( session["loggedIn"] != null && (bool)session["loggedIn"] )
return;
/// if the request is ajax then we return a json object
if ( filterContext.HttpContext.Request.IsAjaxRequest() )
{
filterContext.Result = new JsonResult
{
Data = "UnauthorizedAccess",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
/// otherwise we redirect the user to the login page
else
{
var redirectTarget = new RouteValueDictionary { { "Controller", "Login" }, { "Action", "Index" } };
filterContext.Result = new RedirectToRouteResult(redirectTarget);
}
}
public override void OnResultExecuting ( ResultExecutingContext filterContext )
{
base.OnResultExecuting(filterContext);
/// we set a field 'IsAjaxRequest' in ViewBag according to the actual request type
filterContext.Controller.ViewBag.IsAjaxRequest = filterContext.HttpContext.Request.IsAjaxRequest();
}
}
アクションフィルタの使用場所(グローバル、コントローラ、アクション)
アクションフィルタは、次の3つのレベルに配置できます。
- グローバル
- コントローラ
- アクション
フィルタをグローバルに配置するということは、どのルートへのリクエストでも実行されることを意味します。 コントローラーに1つ配置すると、そのコントローラーの任意のアクションへの要求に対して実行されます。 アクションに1つ配置すると、そのアクションで実行されます。
このシンプルなアクションフィルターがある場合:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class CustomActionFilterAttribute : FilterAttribute, IActionFilter
{
private readonly string _location;
public CustomActionFilterAttribute(string location)
{
_location = location;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
Trace.TraceInformation("OnActionExecuting: " + _location);
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
Trace.TraceInformation("OnActionExecuted: " + _location);
}
}
グローバルフィルタコレクションに追加することで、グローバルレベルで追加することができます。典型的なASP.NET MVCプロジェクトの設定では、これはApp_Start / FilterConfig.csで行われます。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomActionFilterAttribute("Global"));
}
}
コントローラーやアクションレベルでコントローラに追加することもできます:
[CustomActionFilter("HomeController")]
public class HomeController : Controller
{
[CustomActionFilter("Index")]
public ActionResult Index()
{
return View();
}
}
アプリケーションを実行して出力ウィンドウを見ると、次のメッセージが表示されます。
iisexpress.exe Information: 0 : OnActionExecuting: Global
iisexpress.exe Information: 0 : OnActionExecuting: HomeController
iisexpress.exe Information: 0 : OnActionExecuting: Index
iisexpress.exe Information: 0 : OnActionExecuted: Index
iisexpress.exe Information: 0 : OnActionExecuted: HomeController
iisexpress.exe Information: 0 : OnActionExecuted: Global
ご覧のように、リクエストが到着すると、フィルタが実行されます。
- グローバル
- コントローラ
- アクション
グローバルレベルに配置されたフィルタの優れた例は次のとおりです。
- 認証フィルタ
- 承認フィルタ
- ロギングフィルタ
例外ハンドラ属性
この属性はコード内のすべての未処理の例外を処理します(これは主にAjaxリクエスト用ですが、JSONを扱いますが拡張可能です)
public class ExceptionHandlerAttribute : HandleErrorAttribute
{
/// <summary>
/// Overriden method to handle exception
/// </summary>
/// <param name="filterContext"> </param>
public override void OnException(ExceptionContext filterContext)
{
// If exeption is handled - return ( don't do anything)
if (filterContext.ExceptionHandled)
return;
// Set the ExceptionHandled to true ( as you are handling it here)
filterContext.ExceptionHandled = true;
//TODO: You can Log exception to database or Log File
//Set your result structure
filterContext.Result = new JsonResult
{
Data = new { Success = false, Message = filterContext .Exception.Message, data = new {} },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
だから、これに似たJSONレスポンスをいつも送る必要があるとしましょう:
{
Success: true, // False when Error
data: {},
Message:"Success" // Error Message when Error
}
したがって、コントローラのアクションで例外を処理するのではなく、次のようにします。
public ActionResult PerformMyAction()
{
try
{
var myData = new { myValue = 1};
throw new Exception("Handled", new Exception("This is an Handled Exception"));
return Json(new {Success = true, data = myData, Message = ""});
}
catch(Exception ex)
{
return Json(new {Success = false, data = null, Message = ex.Message});
}
}
あなたはこれを行うことができます:
[ExceptionHandler]
public ActionResult PerformMyAction()
{
var myData = new { myValue = 1};
throw new Exception("Unhandled", new Exception("This is an unhandled Exception"));
return Json(new {Success = true, data = myData, Message = ""});
}
または、コントローラレベルで追加できます
[ExceptionHandler]
public class MyTestController : Controller
{
public ActionResult PerformMyAction()
{
var myData = new { myValue = 1};
throw new Exception("Unhandled", new Exception("This is an unhandled Exception"));
return Json(new {Success = true, data = myData, Message = ""});
}
}
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow