问题
I have been successfully using the AntiForgery option with Ajax in Orchard Modules for a while. Recently, I have been wanting to change from using the default ContentType = 'application/x-www-form-urlencoded; charset=UTF-8' to a JSON payload (ContentType='application/JSON').
As soon as I do this I get an exception thrown by ASP.NET 'A required anti-forgery token was not supplied or was invalid.'. OK, but how do I go about adding the __RequestVerificationToken while preserving JSON payload?
For reference, here is the code I'm using:
var config = {
url: url,
type: "POST",
data: data ,
dataType: "json",
contentType: "application/json; charset=utf-8"
};
$.ajax(config);
Controller (blows up with 'A required anti-forgery token was not supplied or was invalid.' before it gets here):
[HttpPost]
public ActionResult Update(ShoppingCartItemVM[] items)
{
// do stuff
}
Is this a limitation of the Orchard AntiForgery wrapper or of the MVC AntiForgery functionality? Or am I being stupid (again)?
回答1:
Giscard is correct. I'll dig a bit deeper.
Note: Only the "post" results in orchard controller require the anti forgery token. So there is less of a requirement to remember that where using a "Get" in a request for json.
Often you will want to send more data than just the request token. In that case the 'data' object you send with your request must contain that __RequestVerificationToken value. In that case jQuery is useful for example:
var defaultPostValues = { __RequestVerificationToken:'@Html.AntiForgeryTokenValueOrchard()', id: 1, ..etc.. };
var myValues = { answers: [1,5,5,10] };
var data = $.extend({}, defaultPostValues, myValues);
var config = {
url: url,
type: "POST",
data: data ,
dataType: "json",
contentType: "application/json; charset=utf-8"
};
$.ajax(config);
The anti-forgery token can also be turned off per module definition (if I remember correctly?). Module.txt
Name: Polls
AntiForgery: false
Author: Matt
... removed for brevity
Features:
Polls
... etc
However I would recommend using the antiforgery if your calls are within Orchard's modules, and disabling if and only if your data is needed else where by external requests. But I would recommend WebAPI within Orchard for that case but that creates a whole new story and probably likely moves far out of scope.
回答2:
Maybe try this:
data = {color: 'red', weight:'20lbs'};
// do some more work...
// Append the anti-forgery token to the POST values:
data['__RequestVerificationToken'] = '@Html.AntiForgeryTokenValueOrchard()';
// Make the .ajax() call:
var config = {
url: url,
type: "POST",
data: data ,
dataType: "json",
contentType: "application/json; charset=utf-8"
};
$.ajax(config);
If you are forming the json somewhere other than a razor view, you can do the @Html.AntiForgeryTokenValueOrchard()
inside a razor view and pass it to a javascript object or variable so you can add it to the json via javascript.
EDIT: In addition to the method Matthew posted, you can also append the anti-forgery token to the POST values right before you make the AJAX call without using .extend(). Example: http://jsfiddle.net/JC66L/.
来源:https://stackoverflow.com/questions/12504090/antiforgery-and-json-incompatible