asp.net-mvc
Aktionsfilter
Suche…
Ein Protokollierungsaktionsfilter
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");
}
}
Sitzungssteuerungs-Aktionsfilter - Seiten- und Ajax-Anforderung
Normalerweise werden Authentifizierungs- und Autorisierungsprozesse in .net MVC durch integrierte Cookies und Token unterstützt. Wenn Sie sich jedoch dazu entscheiden, dies mit Session
selbst zu tun, können Sie die folgende Logik für Seitenanfragen und für Ajax-Anforderungen verwenden.
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();
}
}
Verwendungsorte für Aktionsfilter (global, Controller, Aktion)
Sie können Aktionsfilter auf drei möglichen Ebenen platzieren:
- Global
- Regler
- Aktion
Wenn Sie einen Filter global platzieren , wird er bei Anforderungen an eine beliebige Route ausgeführt. Wenn Sie einen Controller auf einem Controller platzieren, wird er bei Anforderungen für jede Aktion in diesem Controller ausgeführt. Wenn Sie eine Aktion auf eine Aktion setzen , wird diese mit der Aktion ausgeführt.
Wenn wir diesen einfachen Aktionsfilter haben:
[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);
}
}
Wir können es auf globaler Ebene hinzufügen, indem wir es der globalen Filtersammlung hinzufügen. Beim typischen ASP.NET MVC-Projekt-Setup wird dies in App_Start / FilterConfig.cs durchgeführt.
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomActionFilterAttribute("Global"));
}
}
Wir können es auch auf Controller- und Aktionsebene wie in einem Controller hinzufügen:
[CustomActionFilter("HomeController")]
public class HomeController : Controller
{
[CustomActionFilter("Index")]
public ActionResult Index()
{
return View();
}
}
Wenn wir die Anwendung ausführen und das Ausgabefenster betrachten, werden folgende Meldungen angezeigt:
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
Wie Sie sehen, werden die Filter ausgeführt, wenn die Anforderung eingeht:
- Global
- Regler
- Aktion
Hervorragende Beispiele für auf globaler Ebene platzierte Filter sind:
- Authentifizierungsfilter
- Berechtigungsfilter
- Protokollierungsfilter
Ausnahmebehandlungsattribut
Dieses Attribut behandelt alle nicht behandelten Ausnahmen im Code (meistens für Ajax-Anfragen - die sich mit JSON befassen -, kann aber erweitert werden)
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
};
}
}
Nehmen wir also an, Sie müssen immer eine ähnliche JSON-Antwort senden:
{
Success: true, // False when Error
data: {},
Message:"Success" // Error Message when Error
}
Statt Ausnahmen in Controller-Aktionen zu behandeln, wie folgt:
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});
}
}
Du kannst das:
[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 = ""});
}
ODER Sie können auf Controller-Ebene hinzufügen
[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 = ""});
}
}