Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC using Action Filter to check for parameters in URL. stop action from executing

I want to make the following:

when the url doesn't have an instID, i want to redirect to the "Instelling" action

in this controller, every method needs the instID.

        [RequiredParameter(parameterName="instID", controllerToSend="Instelling")]
        public ActionResult Index(int? instID) {
            //if (!instID.HasValue) {
            //    return RedirectToAction("Index", "Instelling");
            //}

            var facts = _db.Instellingens.First(q => q.Inst_ID == instID).FacturatieGegevens;

            return View(facts);
        }

so this is in the controller.

the actionfilter:

namespace MVC2_NASTEST.Controllers {
    public class RequiredParameterAttribute : ActionFilterAttribute {

        public string parameterName { get; set; }
        public string actionToSend { get; set; }
        public string controllerToSend { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext) {

            if (parameterName != string.Empty) {
                if (filterContext.ActionParameters.ContainsKey(parameterName) && filterContext.ActionParameters[parameterName] != null) {
                    string s = "test";
                    //all is good
                } else {
                    //de parameter ontbreekt. kijk of de controller en de action geset zijn.
                    if (actionToSend == string.Empty)
                        actionToSend = "Index";
                    if (controllerToSend == string.Empty) {
                        controllerToSend = filterContext.Controller.ToString();
                        controllerToSend = controllerToSend.Substring(controllerToSend.LastIndexOf(".") + 1);
                        controllerToSend = controllerToSend.Substring(0, controllerToSend.LastIndexOf("Controller"));
                    }

                    UrlHelper helper = new UrlHelper(filterContext.RequestContext);
                    string url = helper.Action(actionToSend, controllerToSend);

                    HttpContext.Current.Response.Redirect(url);
                    //filterContext.HttpContext.Response.Redirect(url, true);
                }
            }

            base.OnActionExecuting(filterContext);
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext) {


            base.OnActionExecuted(filterContext);
        }

    }
}

the thing is: it does work, however, the action itself first gets executed, THEN the redirect happens. this is not what I wanted.

Perhaps i shouldnt use actionfilters but just add a route? in this case, how would i redirect the route to another controller if the instID is missing?

like image 777
Stefanvds Avatar asked Oct 07 '10 15:10

Stefanvds


People also ask

Is it possible to cancel filter execution?

You can cancel filter execution in the OnActionExecuting and OnResultExecuting methods by setting the Result property to a non-null value.

Which action filter executes last in an MVC application?

Exception Filters − Exception filters are the last type of filter to run. You can use an exception filter to handle errors raised by either your controller actions or controller action results.

Which of the filters execute before an action is called?

Authorization filters are used to implement authentication and authorization for controller actions. For example, the Authorize filter is an example of an Authorization filter. Action filters contain logic that is executed before and after a controller action executes.


1 Answers

Rather than creating an action filter (which runs just before the return of the action method), you could consider changing to an Authorization Filter which would allow you to redirect to an alternative controller & action

Something like this (pseudo code):

public class RequiredParameterAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        // read instID from QueryString
        // if instId is null, return false, otherwise true
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.result = new RedirectToRouteResult( new { controller = "MyController" , action = "MyAction" }  )
    }

}

like image 160
Clicktricity Avatar answered Sep 22 '22 12:09

Clicktricity