-1

I am running MVC3, .Net 4 and VS2010. I have following sample project to illustrate the problem.

My controller code

namespace AntiForgeAjaxTest.Controllers
{
    public class IndexController : Controller
    {
        public ActionResult Index()
        {
            MyData d = new MyData();
            d.Age = 20;
            d.Name = "Dummy";
            return View(d);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(MyData data)
        {
            NameValueCollection nc = Request.Form;
            return View(data);
        }

        protected override void ExecuteCore()
        {
            base.ExecuteCore();
        }
    }
}

My view and JavaScript code

@model AntiForgeAjaxTest.Models.MyData

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <title>Index</title>
    <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
    <script src="../../Scripts/json2.js" type="text/javascript"></script>
</head>
<body>
@using (Html.BeginForm("Index", "Index"))
{ 
    @Html.AntiForgeryToken()

    <table>
        <tr>
            <td>Age</td>
            <td>@Html.TextBoxFor(x => x.Age)</td>
        </tr>
        <tr>
            <td>Name</td>
            <td>@Html.TextBoxFor(x => x.Name)</td>
        </tr>
    </table>

    <input type="submit" value="Submit Form" /> <input type="button" id="myButton" name="myButton" value="Ajax Call" />
}

<script type="text/javascript">
    $(document).ready(function () {

        $('#myButton').click(function () {
            var myObject = {
                __RequestVerificationToken: $('input[name=__RequestVerificationToken]').val(),
                Age: $('#Age').val(),
                Name: $('#Name').val(),
            };

            alert(JSON.stringify(myObject));

            $.ajax({
                type: 'POST',
                url: '/Index/Index',
                dataType: 'json',
                contentType: 'application/json; charset=utf-8',
                data: JSON.stringify(myObject),
                success: function (result) {
                    alert(result);
                },
                error: function (request, error) {
                    alert(error);
                }
            });
        });
    });
</script>
</body>
</html>

Here I have 2 buttons, the first one triggers form post, the second one triggers Ajax post. The form post works fine, but the Ajax one does not, the server complains A required anti-forgery token was not supplied or was invalid. even though I have included the token in my JSON already.

Any idea what is wrong with my code?

hardywang
  • 3,996
  • 7
  • 54
  • 88

1 Answers1

1

This code works.

@model AntiForgeAjaxTest.Models.MyData

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <title>Index</title>
    <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
    <script src="../../Scripts/json2.js" type="text/javascript"></script>
</head>
<body>
@using (Html.BeginForm("Index", "Index"))
{ 
    @Html.AntiForgeryToken()

    <table>
        <tr>
            <td>Age</td>
            <td>@Html.TextBoxFor(x => x.Age)</td>
        </tr>
        <tr>
            <td>Name</td>
            <td>@Html.TextBoxFor(x => x.Name)</td>
        </tr>
    </table>

    <input type="submit" value="Submit Form" /> <input type="button" id="myButton" name="myButton" value="Ajax Call" />
}

<script type="text/javascript">
    $(document).ready(function () {

        $('#myButton').click(function () {
            post();
        });
    });

    function post() {
        var myObject = {
            __RequestVerificationToken: $('input[name=__RequestVerificationToken]').val(),
            Age: $('#Age').val(),
            Name: $('#Name').val(),
        };

        $.post('/Index/Index/', myObject);
    }

</script>
</body>
</html>
hardywang
  • 3,996
  • 7
  • 54
  • 88
  • I'm confused how this is any different. $.post is simply a shortcut for $.ajax, so the the data is the same. The only difference is that the default content type is application/x-www-form-urlencoded; charset=UTF-8 if not specified, so I am back to square one. If you are posting an object model, this still doesn't work. I'm starting to wondering if this can be done. – iGanja May 04 '13 at 06:33