ASP.NET MVC Ajax Redirect


I’ve had several occasions where I have needed to make an Ajax request to a secure action on the server (i.e. an action that requires the user to be logged in). The problem is…sometimes the user’s session will timeout between the time they access the secure page and the time they make the secure Ajax request. My action notices this and redirects the user to the login page…but if its an Ajax request then a simple 302 redirect just won’t work. Here’s a method that will.

public class MyBaseController : System.Web.Mvc.Controller
{
    protected override RedirectResult Redirect(string url)
    {
        return new AjaxAwareRedirectResult(url);
    }
}

public class AjaxAwareRedirectResult : RedirectResult
{
    public AjaxAwareRedirectResult(string url)
        : base(url)
    {
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            string destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);

            JavaScriptResult result = new JavaScriptResult()
            {
                Script = "window.location='" + destinationUrl + "';"
            };
            result.ExecuteResult(context);
        }
        else
            base.ExecuteResult(context);
    }
}

Now you can use the controller’s Redirect() function as usual…and it will automatically detect if it needs to perform a 302 redirect or an Ajax redirect.

Cheers!

21 thoughts on “ASP.NET MVC Ajax Redirect

  1. Brilliant! I modified it to work with RedirectResult also (so that it’s compatible with T4MVC). Many, many thanks.

  2. it seems that i need to change the script to:
    “window.location='” + destinationUrl + “‘;”
    to make it work for me

  3. sorry, it seems removed the script tag.

    I mean I need to add the script tag around the line to make it works

  4. Hey nice post. I wanted to use your code but couldn’t modify the RedirectResult class, mostly because I’m using the strongly typed redirect helpers from MvcContrib and because I didn’t want to worry about always substituting a base class. So I went about it another way. Just create a new type of ActionResult attribute then just tag your controllers with it:

    public class AjaxRedirectAttribute : ActionFilterAttribute
    {
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
    var result = filterContext.Result as RedirectResult;
    if (result != null && filterContext.HttpContext.Request.IsAjaxRequest())
    {
    string destinationUrl = UrlHelper.GenerateContentUrl(result.Url, filterContext.HttpContext);

    filterContext.Result = new JavaScriptResult()
    {
    Script = “window.location='” + destinationUrl + “‘;”
    };
    }
    }
    }

    Put [AjaxRedirect] over your controller. Then, you don’t have to worry about subclassing RedirectResult. It’ll just work!

  5. sorry.
    this is my correct controller:

    Function Create(ByVal tbl As Table1) As ActionResult
    db.AddToTable1(tbl)
    db.SaveChanges()
    Return RedirectToAction(“Index”)
    End Function

  6. […] When a session times out, upon posting to the application, mvc2 returns a redirect, which prompts the browser to retrieve my login page, which it then embeds within the current page. This produced one view embedded within my current view, which is obviously undesirable. I attempted to implement the solution referred to in other posts on SO, which outline steps similar to the ones in this blog post: http://craftycodeblog.com/2010/05/15/asp-net-mvc-ajax-redirect/ […]

Leave a reply to meysam Cancel reply