9

In building a custom ASP.MVC 3 Action Filter, how should I redirect the user to another action if my test fails? I would like to pass along the original Action so that I can redirect back to the original page after the user enters the missing preference.

In controller:

[FooRequired]
public ActionResult Index()
{
    // do something that requires foo
}

in a custom filter class:

// 1. Do I need to inherit ActionFilterAttribute or implement IActionFilter?
public class FooRequired : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (TestForFoo() == false)
        {
            // 2. How do I get the current called action?

            // 3. How do I redirect to a different action,
            // and pass along current action so that I can
            // redirect back here afterwards?
        }

        // 4. Do I need to call this? (I saw this part in an example)
        base.OnActionExecuting(filterContext);            
    }
}

I'm looking for a simple ASP.MVC 3 filter example. So far my searches have lead to Ruby on Rails examples or ASP.MVC filter examples much more complicated than I need. I apologize if this has been asked before.

Dan Sorensen
  • 11,403
  • 19
  • 67
  • 100
  • possible duplicate of [ASP.NET MVC 3 Redirect From Action Filter Attribute](http://stackoverflow.com/questions/5453338/asp-net-mvc-3-redirect-from-action-filter-attribute) – Talljoe May 05 '11 at 22:54
  • 1
    That answers part of my question for sure. I didn't get that one in my search of StackOverflow before I asked. Still wondering how to pass along the existing Action. – Dan Sorensen May 05 '11 at 23:17
  • @Talljoe and mods: More like a possible duplicate of [Redirecting to specified controller and action in asp.net mvc action filter](http://stackoverflow.com/questions/1490401/redirecting-to-specified-controller-and-action-in-asp-net-mvc-action-filter) – Matt Sach Jul 02 '12 at 16:19

2 Answers2

9

Here's a small code sample using one of my own Redirect filters:

public class PrelaunchModeAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //If we're not actively directing traffic to the site...
        if (ConfigurationManager.AppSettings["PrelaunchMode"].Equals("true"))
        {
            var routeDictionary = new RouteValueDictionary {{"action", "Index"}, {"controller", "ComingSoon"}};

            filterContext.Result = new RedirectToRouteResult(routeDictionary);
        }
    }
}

If you want to intercept the route, you can get that from the ActionExecutingContext.RouteData member.

With that RouteData member, you can get the original route:

var currentRoute = filterContext.RouteData.Route;

Etc... Does that help answer your question?

Aaronontheweb
  • 8,224
  • 6
  • 32
  • 61
6

You can set the filterContext.Result to a RedirectToRouteResult:

filterContext.Result = new RedirectToRouteResult(...);
Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Shane Andrade
  • 2,655
  • 17
  • 20
  • 1
    This works for me with the exception that I'm still trying to figure out how to pass along the current route so that I know which action was interrupted. – Dan Sorensen May 05 '11 at 23:44
  • I'm guessing that this is the missing ingredient: http://www.squaredroot.com/2008/04/01/redirecttoaction-with-parameter/ – Dan Sorensen May 05 '11 at 23:45