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!

About these ads

21 thoughts on “ASP.NET MVC Ajax Redirect

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

  2. 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!

  3. sorry.
    this is my correct controller:

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

  4. […] 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

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s