Redirect and Ajax Redirect in MVC
In the sample example I will have various methods to perform redirects from main page to “About” page of a simple MVC site. In my opinion, there are only 3 cases – 2 goods and one bad – to perform redirection with or without Ajax.
First case: A sample redirect and a sample link:
The action is
public ActionResult RedirectToAboutNoAjax() { return RedirectToAction("About"); }
and in the View I call in a simple <a href, generated by :
@Html.ActionLink("Redirect no ajax to about", "RedirectToAboutNoAjax", "Home")
When you click the link, the following happens : a 302 Found answer is send to the browser with the new Location. The browser goes to the page requested.
Second case( not good ajax): Call same action from ajax – in hope that ajax will do the redirect alone, without coding further.Modified only the code that calls the action, transforming to ajax.
<a href="javascript:AjaxNotGoodForRedirect('@Url.Action("RedirectToAboutNoAjax", "Home")')">Redirect not good with ajax - returns the page</a>
What it happens is the same: the ajax code calls the RedirectToAboutNoAjax , that redirects to about – and the result is the page. It is no redirect performed to the page itself – rather, on the ajax itself!And , to proof it, I will show the message of html returned in an message:
Third case( good with ajax): Call a action that returns the new url as a json data parameter and make javascript know that.The action:
[HttpPost] public ActionResult RedirectToAboutWithAjax() { try { //in a real world, here will be multiple database calls - or others return Json(new { ok = true, newurl = Url.Action("About") }); } catch (Exception ex) { //TODO: log return Json(new { ok = false, message = ex.Message }); } }
The javascript:
function AjaxGoodRedirect(urlAction) { $.ajax({ type: "POST", // see http://haacked.com/archive/2009/06/24/json-hijacking.aspx url: urlAction, data: {}, //to send data see more at http://bit.ly/mvc_ajax_jquery datatype: "JSON", contentType: "application/json; charset=utf-8", success: function (returndata) { if (returndata.ok) window.location = returndata.newurl; else window.alert(returndata.message); } } ); }
Note: You can combine the returning the RedirectToAction with Json by checking Request.IsAjaxRequest value and returning either FirstCase, either ThirdCase.
You can find the example for download here
If you want more details, please comment – and I will provide any further explanations.
I noticed two things here, unrelated :
1. The article starts explaining the “how” without the “why”. Like solving a math problem without its statement
2. I like the way you say in the comment “in a real world, here will be multiple database calls”. Optimally there should be only one database call but you didn’t say that. You said “in a real world” which is closer to the truth :))
Well, as long as the developer knows what a redirect is, it should be easy (in HTTP a redirect being a response with code 3** that asks the browser to request another URL instead).
In the second case, I don’t know what the
AjaxNotGoodForRedirect(…) function
is actually doing inside..
Well, i for one agree with Tudor on this one about the redirect beeing done http headers with HTTP 301 (http://en.wikipedia.org/wiki/URL_redirection)(http://en.wikipedia.org/wiki/HTTP_301).
Besides the fac that each method described also does the actual redirect, redirecting by 301 will not affect your site’s SEO rank, because search engines look for this error code.
I was thinking along site of creating your own custom ActionFilterAttribute and overriding the header response and then decorating your obsolete action method with this attribute.
(note : code is not tested but i have added this way custom attributes before) :
public class RedirectFilter : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var responseHeader = actionContext.Response.Headers;
responseHeader.Clear();
responseHeader.Add(“HTTP/1.1”, “301 Moved Permanently”);
responseHeader.Add(“Location:”, “http://www.my-new-site-location.com/”);
responseHeader.Add(“Content-Type:”, “text/html”);
base.OnActionExecuting(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
}
}
Nice work.
Thanks for this, maybe a html helper to build the Ajax anchor link would also be useful to make this reusable.
It implies both: a javascript code and a server code….
Good work. I have a couple of suggestions to help the reader.
1- For the 2nd example (Bad AJAX) show the javascript function code so the user can see the complete problem (like you show for the 3rd (Good AJAX example)
2- For the 3rd Example (Good AJAX) Show the code for the link that calls the AjaxGoodRedirect(urlAction) function.
I love the article, this pained me for a long time about a year ago. Just a couple of suggestions to make it even better.
Thank you. I will do it
returning a status(may be boolean) from .cs can decide in javascript whether to redirect is needed or not
Thank you so much.This solution helped me a lot.
if i have a left menu hyper link in a partial view of layout which on click should redirect to a controller action with menu id for the content page to load. at the same time i want the menu id to be used to load another “sub menu” partial view. how to pass the menu id from the url to the partial view action?
you pass to an action that answers with the view. The action passes to the view.
I’m really thank you to you for your artical really helped me !!!!! Thanks!!!!
Thanks!
Aw, this was an incredibly nice post. Taking a few minutes and actual effort to make a very good article… but what can I say…
I procrastinate a lot and don’t seem to get nearly
anything done.