I am using the code as below of this post:
First I will fill an array variable with the correct values for the controller action.
Using the code below I think it should be very straightforward by just adding the following line to the JavaScript code:
data["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();
The <%= Html.AntiForgeryToken() %>
is at its 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(); }
});
}
You should place AntiForgeryToken in a form tag:
then in javascript modify the following code to be
then you should be able to validate the request using ActionResult annotations
i hope this helps.
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.
AJAX based model posting with AntiForgerytoken can be made bit easier with Newtonsoft.JSON library
Below approach worked for me:
Keep your AJAX post like this:
Then in your MVC action:
Hope this helps :)
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 ofJSON
for sending your request parameters:Number 2: Separate the request into two parameters:
So in all cases you need to POST the
__RequestVerificationToken
value.You can set $.ajax 's
traditional
attribute and set it totrue
, to send json data as url encoded form. Make sure to settype:'POST'
. With this method you can even send arrays and you do not have to use JSON.stringyfy or any changes on server side (e.g. creating custom attributes to sniff header )I have tried this on ASP.NET MVC3 and jquery 1.7 setup and it's working
following is the code snippet.
This will match with MVC action with following signature
I had to be a little shady to validate anti-forgery tokens when posting JSON, but it worked.
But, as a few people already mentioned, the validation only checks the form - not JSON, and not the query string. So, we overrode the attribute's behavior. Re-implementing all of the validation would have been terrible (and probably not secure), so I just overrode the Form property to, if the token were passed in the QueryString, have the built-in validation THINK it was in the Form.
That's a little tricky because the form is read-only, but doable.
...
There's some other stuff that's different about our solution (specifically, we're using an HttpModule so we don't have to add the attribute to every single POST) that I left out in favor of brevity. I can add it if necessary.