I want to check some things about the state of the session, the user agent, etc, and possibly take action and return a special view BEFORE a controller method gets a chance to execute. For example:
Most common:
User requests Home/Index
System checks to make sure x != 0.
x does not equal zero, so the Home/Index controller executes like normal.
But, sometimes:
User requests Home/Index
System checks to make sure x != 0.
x DOES equal zero. The user must be notified and the requested controller action cannot be allowed to execute.
I think this involves the use of ActionFilters. But I have read about them and I don't understand if I can preempt the controller method and return a view before it executes. I am sure I could execute code before the controller method runs, but how do I keep it from running in some instances and return a custom view, or direct to a different controller method?
Update: I implemented RM's solution. This is what I did:
public class MyAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (myValue == wrongValue) { filterContext.Result = new ViewResult{ViewName = "Notice"}; } base.OnActionExecuting(filterContext); } }
Now, when myValue is wrong, those users get the Notice view and the requested controller is never executed. To make this work I applied it to a ControllerBase that all my Controllers inherit from.
Yes, completely possible. And, it can be multiple views, or even a FileResult or other result type.
By default, the Index() method is a default action method for any controller, as per configured default root, as shown below. routes. MapRoute( name: "Default", url: "{controller}/{action}/{id}/{name}", defaults: new { controller = "Home", action = "Index", id = UrlParameter. Optional });
All depends what exactly you want to do, and how. Three options below:
You can use route constraints for this. They are executed when evaluating the route to match to.
routes.MapRoute( "HomeWithConstraint", "Home/{action}", new {controller="Home", action="index"}, new { x = new MyCustomRouteConstraint () } ); // without constraint, i.e. if above didnt pass routes.MapRoute( "HomeWithConstraint", "Home/{action}", new {controller="Home", action="index"} );
The MyCustomRouteConstraint type above would check for x==0 etc in your example. Not sure exactly what you want to do, but this will allow you to check conditions before running and set additional route values etc.
See here for example of custom route constraints.
Alternativly, yes you can use a custom ActionFilter, just apply it to the controller class, and it will be called before any action is executed. Something like:
public class CheckXActionFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if(x == 0) { // do something // e.g. Set ActionParameters etc } else { // do something else } } }
Another option is to have all you controllers (or the relevant ones) inherit from a custom controller you make, and override :
OnActionExecuting
See here for details.
To do the same as the filter, or routing constraints.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With