asp.net-mvc
Actiefilters
Zoeken…
Een logging-actiefilter
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");
}
}
Session Control actiefilter - pagina & Ajax-aanvraag
Meestal worden authenticatie- en autorisatieprocessen uitgevoerd door ingebouwde cookie- en tokenondersteuning in .net MVC. Maar als u besluit het zelf te doen met Session
, kunt u de onderstaande logica gebruiken voor zowel paginaverzoeken als ajaxverzoeken.
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();
}
}
Actiefiltergebruik locaties (globaal, controller, actie)
U kunt actiefilters op drie mogelijke niveaus plaatsen:
- Globaal
- controleur
- Actie
Door een filter wereldwijd te plaatsen, wordt het uitgevoerd op aanvragen voor elke route. Door er een op een controller te plaatsen, wordt deze uitgevoerd op verzoeken om elke actie in die controller. Als je er een op een actie plaatst, betekent dit dat deze met de actie wordt uitgevoerd.
Als we dit eenvoudige actiefilter hebben:
[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);
}
}
We kunnen het op wereldwijd niveau toevoegen door het toe te voegen aan de globale filtercollectie. Met de typische ASP.NET MVC-projectinstellingen gebeurt dit in App_Start / FilterConfig.cs.
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomActionFilterAttribute("Global"));
}
}
We kunnen het ook toevoegen op controller en actieniveau zoals in een controller:
[CustomActionFilter("HomeController")]
public class HomeController : Controller
{
[CustomActionFilter("Index")]
public ActionResult Index()
{
return View();
}
}
Als we de toepassing uitvoeren en naar het venster Uitvoer kijken, zien we de volgende berichten:
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
Zoals u ziet, worden de filters uitgevoerd wanneer het verzoek binnenkomt:
- Globaal
- controleur
- Actie
Uitstekende voorbeelden van filters die op mondiaal niveau zijn geplaatst, zijn onder meer:
- Verificatiefilters
- Autorisatiefilters
- Logfilters
Uitzondering Handler Attribuut
Dit kenmerk verwerkt alle onverwerkte uitzonderingen in de code (dit is meestal voor Ajax-aanvragen - die omgaan met JSON - maar kan worden uitgebreid)
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
};
}
}
Laten we zeggen dat u altijd een JSON-reactie moet sturen die vergelijkbaar is met deze:
{
Success: true, // False when Error
data: {},
Message:"Success" // Error Message when Error
}
Dus in plaats van uitzonderingen af te handelen in controlleracties, gaat u als volgt te werk:
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});
}
}
Je kan dit doen:
[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 = ""});
}
OF u kunt toevoegen op controller-niveau
[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 = ""});
}
}