views:

285

answers:

3

I am using the code as below of this post:

First i will an fill array variable with the correct values for the controller action. Using the code below i think it should be very straigtforward by just adding the following line to the javascript:

data["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();

The <%= Html.AntiForgeryToken() %> is at his right place and the action has a [ValidateAntiForgeryToken]

But my controller action keeps saying: "Invalid forgery token"

What am i doing wrong here?

Code

data["fiscalyear"] = fiscalyear;
data["subgeography"] = $(list).parent().find('input[name=subGeography]').val();
data["territories"] = new Array();

$(items).each(function() {
    data["territories"].push($(this).find('input[name=territory]').val());
});

    if (url != null) {
        $.ajax(
        {
            dataType: 'JSON',
            contentType: 'application/json; charset=utf-8',
            url: url,
            type: 'POST',
            context: document.body,
            data: JSON.stringify(data),
            success: function() { refresh(); }
        });
    }
+2  A: 

What is wrong is that the controller action that is supposed to handle this request and which is marked with the [ValidateAntiForgeryToken] expects a parameter called __RequestVerificationToken to be POSTed along with the request.

There's no such parameter POSTed as you are using JSON.stringify(data) which converts your form to its JSON representation and so the exception is thrown.

So I can see two possible solutions here:

Number 1: Use x-www-form-urlencoded instead of JSON for sending your request parameters:

data["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();
data["fiscalyear"] = fiscalyear;
// ... other data if necessary

$.ajax({
    url: url,
    type: 'POST',
    context: document.body,
    data: data,
    success: function() { refresh(); }
});

Number 2: Separate the request into two parameters:

data["fiscalyear"] = fiscalyear;
// ... other data if necessary
var token = $('[name=__RequestVerificationToken]').val();

$.ajax({
    url: url,
    type: 'POST',
    context: document.body,
    data: { __RequestVerificationToken: token, jsonRequest: JSON.stringify(data) },
    success: function() { refresh(); }
});

So in all cases you need to POST the __RequestVerificationToken value.

Darin Dimitrov
A: 

Check out Dixin's Blog for a great post on doing exactly that.

Also, why not use $.post instead of $.ajax?

Along with the jQuery plugin on that page, you can then do something as simple as:

        data = $.appendAntiForgeryToken(data,null);

        $.post(url, data, function() { refresh(); }, "json");
AlDev
+1  A: 

I hold the token in my JSON object and I ended up modifying the ValidateAntiForgeryToken class to check the InputStream of the Request object when the post is json. I've written a blog post about it, hopefully you might find it useful.

TWith2Sugars