[英]Invoking action from ajax method is throwing an error: The required anti-forgery form field “__RequestVerificationToken” is not present
[英]The required anti-forgery form field "__RequestVerificationToken" is not present when using Ajax and Html.AntiForgeryToken()
我有一個控制器,它有兩種操作方法。 它們都用[ValidateAntiForgeryToken()]
注釋, @Html.AntiForgeryToken()
包含在相應的視圖中。 現在調用這些方法之一( GetVendorOrders
:其結果綁定到劍道網格)成功,另一個( MakeVendorPayment
)拋出異常"The required anti-forgery form field __RequestVerificationToken is not present" even when both are provided with __RequestVerificationToken value.
我嘗試了以下 3 種方式:
在 AJAX 的 headers 參數中傳遞令牌,例如: headers: { '__RequestVerificationToken': token }
在 AJAX 的數據參數中傳遞令牌,例如: data: JSON.stringify({ vendorId: vId, orderIds: oIds, __RequestVerificationToken: token })
附加令牌值並將其傳遞給 AJAX, data.__RequestVerificationToken = token;
--以下是這些操作方法:
[HttpPost]
[ValidateAntiForgeryToken()]
public virtual ActionResult GetVendorOrders(DataSourceRequest command, VendorPaymentSearchModel model)
{
var orders = _orderService.SearchOrders(vendorId: model.VendorId, createdFromUtc: model.StartDate, createdToUtc: model.EndDate);
var gridModel = new DataSourceResult
{
Data = orders.Select(x =>
{
return new OrderModel
{
CustomOrderNumber = x.CustomOrderNumber,
CustomerFullName = x.CustomerFullName,
CustomerEmail = x.CustomerEmail,
OrderTotal = x.OrderTotal,
Commission = x.Commission,
VendorPayment = x.OrderTotal - x.Commission
};
}),
};
return Json(gridModel);
}
[HttpPost]
[ValidateAntiForgeryToken()]
public virtual ActionResult MakeVendorPayment(int vendorId, string[] orderIds)
{
foreach (var orderId in orderIds)
{
var order = _orderService.GetOrderById(Convert.ToInt32(orderId));
var vendorPayment = new VendorPayment()
{
VendorId = vendorId,
OrderId = Convert.ToInt32(orderId),
OrderTotal = order.OrderTotal,
Commission = order.Commission,
Payment = order.OrderTotal - order.Commission
};
_vendorPaymentService.InsertVendorPayment(vendorPayment);
}
return Json(new { Result = true });
}
`//Following are Javascript functions:
//This Call Successful
$(document).ready(function () {
$("#orders-grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "@Html.Raw(Url.Action("GetVendorOrders", "Vendor"))",
type: "POST",
dataType: "json",
data: additionalData
}
},
},
dataBound: onDataBound,
columns: [
{
field: "Id",
field: "Id",
width: 50
},
{
field: "CustomOrderNumber",
title: "Order #",
width: 80
},
{
field: "OrderStatus",
title: "Order Status",
width: 100
},
{
field: "OrderTotal",
title: "Order Total",
width: 100
},
{
field: "Commission",
title: "Commission",
width: 100
},
{
field: "VendorPayment",
title: "VendorPayment",
width: 100
}
]
});`
//This results into error: The required anti-forgery form field "__RequestVerificationToken" is not present.
//Commented parts are the other ways that are tried.
$('#vendor-payment').click(function (e) {
e.preventDefault();
var orderIds = [];
var data = $("#orders-grid").data("kendoGrid").dataSource._data;
for (i = 0; i < data.length; i++) {
orderIds.push(data[i].CustomOrderNumber);
}
//var token = $('input[name=__RequestVerificationToken]').val();
$.ajax({
url: '@Url.Action("MakeVendorPayment", "Vendor")',
type: 'POST',
dataType: 'json',
//cache: false,
//headers: { '__RequestVerificationToken': token },
//data: addAntiForgeryToken({ vendorId: vId, orderIds: oIds }),
data: JSON.stringify({ vendorId: vId, orderIds: oIds, __RequestVerificationToken: token })
contentType: 'application/json; charset=utf-8',
success: function (result) {
console.log(result);
var grid = $("#orders-grid").data("kendoGrid");
grid.dataSource.read();
},
error: function (objAjaxRequest, strError) {
var respText = objAjaxRequest.responseText;
console.log(respText);
}
});
});
function addAntiForgeryToken(data) {
if (!data) {
data = {};
}
var token = $('input[name=__RequestVerificationToken]');
if (token.length) {
data.__RequestVerificationToken = token.val();
}
return data;
};
});
我很驚訝網格綁定的函數(調用 GetVendorOrders)成功,但單擊按鈕(調用 MakeVendorPayment)拋出錯誤:所需的防偽表單字段“__RequestVerificationToken”不存在。
終於在做了一些更多的研究之后,我得到了解決方案。 我只需要在 AJAX 調用中刪除contentType
選項,所以它使用默認的'application/x-www-form-urlencoded; charset=UTF-8'
'application/x-www-form-urlencoded; charset=UTF-8'
並刪除了JSON.stringify() 。
更改的 AJAX 調用如下:
$.ajax({
url: '@Url.Action("MakeVendorPayment", "Vendor")',
type: 'POST',
dataType: 'json',
data: { vendorId: vId, orderIds: oIds, __RequestVerificationToken: token },
success: function (result) {
console.log(result);
var grid = $("#orders-grid").data("kendoGrid");
grid.dataSource.read();
},
error: function (objAjaxRequest, strError) {
var respText = objAjaxRequest.responseText;
console.log(respText);
}
});
由於您使用的是劍道,您還可以使用速記kendo.antiForgeryTokens()為您完成一些繁重的工作,例如
postData('@Url.Action("MakeVendorPayment", "Vendor")', { vendorId: vId, orderIds: oIds });
...
postData: (url, data) => {
$.ajax({
method: "POST",
url: url,
data: $.extend(data, kendo.antiForgeryTokens())
}).done(() => {
viewModel.items.read();
}).fail((e) => {
error_handler(e);
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.