Sam Gentile
Sam Gentile

Reputation: 1349

Translate MVC Ajax.ActionLink to jQuery .post method?

I am dealing with this ASP.NET MVC problem of that using ValidateAntiForgeryToken with AJAX breaks the AJAX call (Using ValidateAntiForgeryToken with Ajax.ActionLink). The only solution (as stated in that topic) requires jQuery.

How do i do the eqvivalent of the following with jQuery's .post method?

@Ajax.ActionLink("Perform HTTPPost", "PostTest", new AjaxOptions{ HttpMethod="POST"})

Here is the Controller:

// [ValidateAntiForgeryToken]
public class MoreInfoController : Controller
{        
    [HttpPost]
    public ActionResult PostTest()
    {
        return View();
    }
}

Here is it's Index VIEW with both Javascript and HTML:

    <script type="text/javascript">
    $(document).ready(function () {
        $('#linkToPost').click(PostForm);
    });

    function PostForm() {
        $.post("/PostTest", $('#testForm').serialize(), function(data) {

        });
        return false;
    }

</script>
<a id="linkToPost" href="#">Perform HTTP Post</a>
<form id="testForm" method="POST" >
    @Html.AntiForgeryToken()
</form>

And here is the Route:

routes.MapRoute("PostTest1",
                            "PostTest",
                            new {controller = "MoreInfo", action = "PostTest"}
        );

Upvotes: 1

Views: 2927

Answers (3)

Sam Gentile
Sam Gentile

Reputation: 1349

This works:

[UseAntiForgeryTokenOnPostByDefault]

    public class MoreInfoController: Controller
    {
       [HttpPost]
       [ValidateAntiForgeryToken]
       public ActionResult PostTest()
       {
           return View();
       }
    }

And the View:

@using (Html.BeginForm("PostTest", "MoreInfo")
{
   @Html.AntiForgeryToken()
   <input type="submit" value="submit"/>
}

where [UseAntiForgeryTokenOnPostByDefault] is http://weblogs.asp.net/srkirkland/archive/2010/04.aspx

Upvotes: 0

amurra
amurra

Reputation: 15401

Assuming your anti forgery token element is in the form you want to post you can do the following:

Here is your link:

<a id="linkToPost" href="#">Perform HTTP Post</a>

Here is the jquery to bind the click of this link to post the form:

<script type="text/javascript">
   $(document).ready(function() {
      $('#linkToPost').click(PostForm);   
});
function PostForm() {
    $.post("/PostTest", $('#idOfyourForm').serialize(), function(data) {
      // do something with the data that comes back from the post 
    });
    return false;
}

</script>

Now what you need to do is replace #idOfYourForm with the actual id of your form:

<form id="TestForm"> you would make it $('#TestForm').serialize()

Next you need to make sure the route I have of /PostTest will actually map to your controller and action. You will need something like this:

context.MapRoute("PostTest1",
                 "PostTest",  // URL with parameters
                 new { controller = "MoreInfoController", action = "PostTest" });

That's it.

Upvotes: 1

Dismissile
Dismissile

Reputation: 33071

My example is using $.ajax but you can easily change it to $.post

@Html.ActionLink("Perform HTTP Post", "PostTest", "Controller", null, new { id = "someId" })

<script type="text/javascript">
    $(function() {
        $('#someId').click(function() {
            $.post({
                url: $(this).attr('href'),
                type: 'post',
                success: function(data) {
                    // assuming you're returning a partial result
                    $('#somecontainer').html(data);
                }
            });

            // prevent the default action
            return false;
        });
    }
</script>

If you don't want to give the anchor an id, you could use a class selector:

$('.ajax-link').click(function() { ... });

Instead of doing new { id = "someId" } you would need to do new { @class = "ajax-link" } or whatever you wanted your class to be named.

edit
I was using the wrong overload. I was trying to set the id for the html attribute, not the route data.

Upvotes: 1

Related Questions