views:

507

answers:

2

I have a link in one of my views that users can click that calls an ActionResult. The link is like so:

<a class="do_something" href="#">lorem ipsum</a>

I then have some javascript that posts to the ActionResult (there is no data passed to the ActionResult) like so:

$("a.do_something").click(function() {
   var urltopost = "/foo";

   $.post(urltopost);
   return false;
});

The ActionResult is intended to then do something, like so:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult foo()
    {
        //do something here

        TempData["Success"] = "You have successfully done something";
        return RedirectToAction("Index", "Home");
    }

What I want to have happen is that when the user clicks the link, the ActionResult does its thing, and then redirects the user to another view, displaying the TempData message letting them know that everything worked correctly.

Everything works fine, except for the redirect part. When the link is clicked, the ActionResult is called, and it does what it is supposed to do, but the view is not redirected.

The question is, how can I redirect the user to the desired view when something happens in the ActionResult? Is it better practice to redirect from jQuery (if so, how can that be done)?

+1  A: 

Your javascript just calls the controller action but it doesn't do anything with the returned value (in this case, the html from the view it redirects to).

You should create a callback function and replace the current html with the returned html from the javascript $.post() call.

As an example, here's some code of mine which posts a form to a controller action which returns a partial view:

            var f = $("#FilterProfile");
            var action = f.attr("action");
            var serializedForm = f.serialize();
            $.post(action,
                serializedForm,
                function(data) {
                    $("tbody").html(data);
                });

Your code should be something like this:

                    $.post("/foo",
                      function(data) {
                          $("html").replaceWith(data);
                      });

I did not test it but you should get the picture. If you have firebug installed on your FF browser, you could see what the $.post() method returns.

If you want to do a "real" redirect and enable the user to use his back button, you could also make the $.post() return the URL of the view to redirect to, and then use location.href = data; to do the redirect.

Thomas Stock
+1  A: 

Why are you even just ajax for this? Just have the link go directly to the action (using GET).

<a class="do_something" href='/foo'>lorem ipsum</a>

[AcceptVerbs( HttpVerbs.Get )]
public ActionResult foo()
{
   // do something

   TempData["Success"] = "You have successfully done something";
   return RedirectToAction("Index","Home");
}

I could see doing it via jQuery if the action is a long running action and you want to provide a spinner or something to indicate that work is going on, but for most actions I would just have the link connect to the action. If you do have a long running action, then I would have your success callback for the post, just set location.href to the correct Url -- and have the action return a text message or html (for errors, etc.). I think you'd need to use the ajax method to get error feedback, tho.

$("a.do_something").click(function() {
   var urltopost = "/foo";

   $.post(urltopost, null, function() { location.href = "/home"; } );
   return false;
});
tvanfosson
In this example you've given, I'm doing something very similar, but I find that TempData isn't available after you do the redirect this way. Is this not a problem you have had? I've only been able to access the TempData when the redirect is done by the Action. Any redirect that I do client side nulls the TempData.
Chops
I can't see how any client-side activity could impact the TempData on the server. I'd have to check the source code to see exactly how the TempData is stored and whether it's stored when returning JSON. I answered this a long time ago, but I don't think I was intending that you would use TempData in the second example. The way I would do it is to send back the error message. Pop up a dialog, then do the redirect to the returned url when the dialog is closed.
tvanfosson