Translate MVC Ajax.ActionLink to jQuery .post meth

2020-07-30 03:16发布

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"}
        );

3条回答
够拽才男人
2楼-- · 2020-07-30 03:33

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.

查看更多
【Aperson】
3楼-- · 2020-07-30 03:37

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

查看更多
爷、活的狠高调
4楼-- · 2020-07-30 03:39

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.

查看更多
登录 后发表回答