views:

2255

answers:

2

I have written an action filter which detects a new session and attempts to redirect the user to a page informing them that this has happened. The only problem is I can not figure out how to make it redirect to a controller/action combo in an action filter. I can instead only figure out how to redirect to a specified url. Is there a direct way to redirect to a controller/action combo in an action filter in mvc2?

+2  A: 

Call RedirectToAction using this overload:

protected internal RedirectToRouteResult RedirectToAction(
    string actionName,
    RouteValueDictionary routeValues
)

In Action Filters, the story is a little different. For a good example, see here:

http://www.dotnetspider.com/resources/29440-ASP-NET-MVC-Action-filters.aspx

Robert Harvey
How do I use this function in an ActionFilter? I have the ActionExecutingContext, which has a Controller property which does not have this function available on it. If you can show me an action filter implementation which uses this function, it would likely be better than my current solution.
NickLarsen
@Nick, see my edit...
Robert Harvey
That is a good place to look for redirecting in an action filter (+1), but I really want specify the controller/action combo to my filter. I also didn't want to just concatenate strings in case of custom routing, but I ended up finding something that could help. See my answer.
NickLarsen
+4  A: 

I ended up using a combination of items to achieve this goal.

First is the session expire filter found here. Then I wanted someway to specify the controller/action combo to get a redirect URL, which I found plenty of examples of here. In the end I came up with this:

public class SessionExpireFilterAttribute : ActionFilterAttribute
{
    public String RedirectController { get; set; }
    public String RedirectAction { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext ctx = HttpContext.Current;

        if (ctx.Session != null)
        {
            if (ctx.Session.IsNewSession)
            {
                string sessionCookie = ctx.Request.Headers["Cookie"];
                if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    UrlHelper helper = new UrlHelper(filterContext.RequestContext);
                    String url = helper.Action(this.RedirectAction, this.RedirectController);
                    ctx.Response.Redirect(url);
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }
}
NickLarsen
If you want to make this more testable, I believe you can simply set filterContext.Result to a RedirectResult, rather than explicitly redirecting. The net result is that MVC will still perform the redirect, but that way you can write unit tests that manually invoke OnActionExecuting() and then assert against filterContext.Result.
Seth Petry-Johnson