How to get an ASP.NET MVC Ajax response to redirect to new page instead of inserting view into UpdateTargetId?

You can use JavascriptResult to achieve this.

To redirect:

return JavaScript("window.location = 'http://www.google.co.uk'");

To reload the current page:

return JavaScript("location.reload(true)");

Seems the simplest option.

You can return a JSON with the URL and change the window.location using JavaScript at client side. I prefer this way than calling a JavaScript function from the server, which I think that it's breaking the separation of concerns.

Server side:

return Json(new {result = "Redirect", url = Url.Action("ActionName", "ControllerName")});

Client side:

if (response.result == 'Redirect')
    window.location = response.url;

Of course you can add more logic because there could be an error on the server side and in that case the result property could indicate this situation and avoid the redirection.

The behavior you're trying to produce is not really best done using AJAX. AJAX would be best used if you wanted to only update a portion of the page, not completely redirect to some other page. That defeats the whole purpose of AJAX really.

I would suggest to just not use AJAX with the behavior you're describing.

Alternatively, you could try using jquery Ajax, which would submit the request and then you specify a callback when the request completes. In the callback you could determine if it failed or succeeded, and redirect to another page on success. I've found jquery Ajax to be much easier to use, especially since I'm already using the library for other things anyway.

You can find documentation about jquery ajax here, but the syntax is as follows:

jQuery.ajax( options )  

jQuery.get( url, data, callback, type)

jQuery.getJSON( url, data, callback )

jQuery.getScript( url, callback )

jQuery.post( url, data, callback, type)

While not elegant, works for me in certain situations.

Controller

if (RedirectToPage)
    return PartialView("JavascriptRedirect", new JavascriptRedirectModel("http://www.google.com"));
else
   ... return regular ajax partialview

Model

    public JavascriptRedirectModel(string location)
    {
        Location = location;
    }

    public string Location { get; set; }

/Views/Shared/JavascriptRedirect.cshtml

@model Models.Shared.JavascriptRedirectModel

<script type="text/javascript">
    window.location = '@Model.Location';
</script>

Using JavaScript will definitely do the job.

You can also use Content if this is more your style.

Example:

MVC Controller

[HttpPost]
public ActionResult AjaxMethod()
{
    return Content(@"http://www.google.co.uk");
}

Javascript

$.ajax({
    type: 'POST',
    url: '/AjaxMethod',
    success: function (redirect) {
        window.location = redirect;
    }
});

You can simply write in Ajax Success like below :

 $.ajax({
            type: "POST",
            url: '@Url.Action("GetUserList", "User")',
            data: { id: $("#UID").val() },
            success: function (data) {
                window.location.href = '@Url.Action("Dashboard", "User")';
            },
            error: function () {
                $("#loader").fadeOut("slow");
            }
});

I needed to do this because I have an ajax login form. When users login successfully I redirect to a new page and end the previous request because the other page handles redirecting back to the relying party (because it's a STS SSO System).

However, I also wanted it to work with javascript disabled, being the central login hop and all, so I came up with this,

    public static string EnsureUrlEndsWithSlash(string url)
    {
        if (string.IsNullOrEmpty(url))
            throw new ArgumentNullException("url");
        if (!url.EndsWith("/"))
            return string.Concat(url, "/");
        return url;
    }

    public static string GetQueryStringFromArray(KeyValuePair<string, string>[] values)
    {
        Dictionary<string, string> dValues = new Dictionary<string,string>();
        foreach(var pair in values)            
            dValues.Add(pair.Key, pair.Value);            
        var array = (from key in dValues.Keys select string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(dValues[key]))).ToArray();
        return "?" + string.Join("&", array);
    }

    public static void RedirectTo(this HttpRequestBase request, string url, params KeyValuePair<string, string>[] queryParameters)
    {            
        string redirectUrl = string.Concat(EnsureUrlEndsWithSlash(url), GetQueryStringFromArray(queryParameters));
        if (request.IsAjaxRequest())
            HttpContext.Current.Response.Write(string.Format("<script type=\"text/javascript\">window.location='{0}';</script>", redirectUrl));
        else
            HttpContext.Current.Response.Redirect(redirectUrl, true);

    }

You can simply do some kind of ajax response filter for incomming responses with $.ajaxSetup. If the response contains MVC redirection you can evaluate this expression on JS side. Example code for JS below:

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data && typeof data == "string") {
            if (data.indexOf('window.location') > -1) {
                eval(data);
            }
        }
        return data;
    }
});

If data is: "window.location = '/Acount/Login'" above filter will catch that and evaluate to make the redirection.

How about this :

public ActionResult GetGrid()
{
   string url = "login.html";
   return new HttpStatusCodeResult(System.Net.HttpStatusCode.Redirect,url)
}

And then

$(document).ajaxError(function (event, jqxhr, settings, thrownError) { 
   if (jqxhr.status == 302) {
      location.href = jqxhr.statusText;
   }           
});

Or

error: function (a, b, c) {
       if (a.status == 302) {
         location.href = a.statusText;
       }  
}
Asif Ashraf

I m not satisfied by the best answer by the Joseph, instead of fixing the correct problem, he told that this is wrong use case. In fact there are many places for example if you are converting an old codebase to ajaxified code and there you NEED it, then you NEED it. In programming there is no excuse because its not only you who is coding its all bad and good developers and you have to work side by side. So if I don't code redirection in ajax my fellow developer can force me to have a solution for it. Just like I like to use all AMD patterned sites or mvc4, and my company can keep me away from it for a year.

So let's talk on the solution now.

I have done hell heck of ajax request and response handling and the simplest way I found out was to send status codes to the client and have one standard javascript function to understand those codes. If i simply send for example code 13 it might meant a redirect.

So a json response like { statusCode: 13, messsage: '/home/logged-in' } of course there are tons of variations proposed like { status: 'success', code: 13, url: '/home/logged-in', message: 'You are logged in now' }

etc , so up to your own choice of standard messages

Usually I Inherit from base Controller class and put my choice of standard responses like this

public JsonResult JsonDataResult(object data, string optionalMessage = "")
    {
        return Json(new { data = data, status = "success", message = optionalMessage }, JsonRequestBehavior.AllowGet);
    }

    public JsonResult JsonSuccessResult(string message)
    {
        return Json(new { data = "", status = "success", message = message }, JsonRequestBehavior.AllowGet);
    }

    public JsonResult JsonErrorResult(string message)
    {
        return Json(new { data = "", status = "error", message = message }, JsonRequestBehavior.AllowGet);
    }

    public JsonResult JsonRawResult(object data)
    {
        return Json(data, JsonRequestBehavior.AllowGet);
    }

About using $.ajax intead of Ajax.BeginForm I would love to use Jquery ajax and I do, but again its not me in the whole world to make decisions I have an application full of Ajax.BeginForm and of course I didnt do that. But i have to live with it.

So There is a success callback in begin form too, you don't need to use jquery ajax to use callbacks Something about it here Ajax.BeginForm, Calls Action, Returns JSON, How do I access JSON object in my OnSuccess JS Function?

Thanks

If you're redirect from the JavaScript class

same view - diferent controller

<strike>window.location.href = `'Home'`;</strike>

is not same view

<strike>window.location.href = `'Index/Home'`;</strike>

Add a helper class:

public static class Redirector {
        public static void RedirectTo(this Controller ct, string action) {
            UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext);

            ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action));
        }

        public static void RedirectTo(this Controller ct, string action, string controller) {
            UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext);

            ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller));
        }

        public static void RedirectTo(this Controller ct, string action, string controller, object routeValues) {
            UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext);

            ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller, routeValues));
        }
    }

Then call in your action:

this.RedirectTo("Index", "Cement");

Add javascript code to any global javascript included file or layout file to intercept all ajax requests:

<script type="text/javascript">
  $(function() {
    $(document).ajaxComplete(function (event, xhr, settings) {
            var urlHeader = xhr.getResponseHeader('AjaxRedirectURL');

            if (urlHeader != null && urlHeader !== undefined) {
                window.location = xhr.getResponseHeader('AjaxRedirectURL');
            }
        });
  });
</script>

As ben foster says you can return the Javascripts and it will redirect you to the desired page.

To load page in the current page:

return JavaScript("window.location = 'http://www.google.co.uk'");'

To load page in the new tab:

return JavaScript("window.open('http://www.google.co.uk')");

You can get a non-js-based redirection from an ajax call by putting in one of those meta refresh tags. This here seems to be working: return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");

Note: I discovered that meta refreshes are auto-disabled by Firefox, rendering this not very useful.