asp.net-mvc
Åtgärdsfilter
Sök…
Ett loggningsfilter
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-åtgärdsfilter - sida & ajax-begäran
Vanligtvis utförs autentiserings- och auktoriseringsprocesser av inbyggda cookie- och token-stöd i .net MVC. Men om du väljer att göra det själv med Session
du använda nedanstående logik för både sidförfrågningar och ajaxförfrågningar.
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();
}
}
Användningsplatser för åtgärdsfilter (global, controller, action)
Du kan placera actionfilter på tre möjliga nivåer:
- Global
- Kontrollant
- Verkan
Att placera ett filter globalt innebär att det kommer att köras på förfrågningar till valfri rutt. Om du placerar en på en controller gör det att den körs på begäran till alla åtgärder i den kontrollenheten. Att placera en på en åtgärd betyder att den körs med åtgärden.
Om vi har detta enkla åtgärdsfilter:
[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);
}
}
Vi kan lägga till den på global nivå genom att lägga till den i den globala filtersamlingen. Med den typiska ASP.NET MVC-projektuppsättningen görs detta i App_Start / FilterConfig.cs.
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomActionFilterAttribute("Global"));
}
}
Vi kan också lägga till det på controller och åtgärdsnivå som i en controller:
[CustomActionFilter("HomeController")]
public class HomeController : Controller
{
[CustomActionFilter("Index")]
public ActionResult Index()
{
return View();
}
}
Om vi kör applikationen och tittar på Output-fönstret ser vi följande meddelanden:
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
Som du kan se, när förfrågan kommer in, körs filtren:
- Global
- Kontrollant
- Verkan
Utmärkta exempel på filter placerade på global nivå inkluderar:
- Autentiseringsfilter
- Autoriseringsfilter
- Loggarfilter
Attribut för undantagshanterare
Detta attribut hanterar alla obehandlade undantag i koden (detta är mestadels för Ajax-förfrågningar - som handlar om JSON - men kan utökas)
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
};
}
}
Så låt oss säga att du alltid måste skicka ett JSON-svar som liknar detta:
{
Success: true, // False when Error
data: {},
Message:"Success" // Error Message when Error
}
Så istället för att hantera undantag i controlleråtgärder, så här:
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 kan göra det här:
[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 = ""});
}
ELLER du kan lägga till på Controller-nivå
[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 = ""});
}
}