问题描述
我在控制器中有以下方法
I have the following method in controller
[HttpPost]
[Authorize(Roles ="Klient")]
[ValidateAntiForgeryToken]
public ActionResult GetAvaiableHouses(DateTime startDate, DateTime endDate)
{
Session.Remove("Reservation");
IEnumerable <SelectListItem> avaiableHouses = repository.GetAllNamesAvaiableHouses(repository.GetAvaiableHousesInTerm(startDate, endDate));
List<string> houses = new List<string>();
avaiableHouses.ToList().ForEach(item => houses.Add(item.Value));
if(avaiableHouses.ToList().Count == 0)
{
return new EmptyResult();
}
Session["Reservation"] = new NewReservation()
{
StartDate = startDate,
EndDate = endDate,
AvaiableHouses = avaiableHouses
};
return PartialView("~/Views/Shared/_AvaiableHousesPartial.cshtml", houses);
}
通过在View.cshtml中使用Ajax脚本来调用此方法
This method is called by using ajax script in View.cshtml
$(function () {
$("#btnCheckAvaiableHouses").click(function () {
$.ajax({
type: "POST",
url: "/ClientReservations/GetAvaiableHouses",
data: '{startDate: "' + $("#startdate").val() + '",endDate:"' + $("#enddate").val() + '",__RequestVerificationToken:"' + $('input[name=__RequestVerificationToken]').val() +'" }',
contentType: "application/json; charset=utf-8",
dataType: "text",
success: function (response) {
$('#avaiableHouses').html(response)
if (!$('#avaiableHouses').is(':empty')) {
document.getElementById("btnConfirmTerm").style.visibility = 'visible';
}
else {
$('#avaiableHouses').html('Brak dostępnych domków w podanym terminie')
}
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
这是带有此按钮的按钮部分,称为该脚本
This is the section of buttons with this one which call this script
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" id="btnCheckAvaiableHouses" value="Sprawdź dostępność domków" class="btn btn-default" />
<input type="button" id="btnConfirmTerm" value="Potwierdź termin" onclick="location.href='@Url.Action("Create", "ClientReservations")'" class="btn btn-default" style="visibility:hidden" />
</div>
</div>
我添加了其他参数
'",__RequestVerificationToken:"' + $('input[name=__RequestVerificationToken]').val()
进入ajax脚本,但是在执行过程中我仍然收到错误
into ajax script but during execution I still receive the error
可能是什么原因?
推荐答案
如果对数据进行字符串化处理并使用contentType: 'application/json
,则将令牌添加到ajax标头中,例如
If your stringifying the data and using contentType: 'application/json
, then add the token to the ajax headers, for example
var headers = { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val() };
$.ajax({
headers: headers,
data: ... // remove the token from your existing implementation
....
});
,然后您需要创建一个自定义FilterAttribute
以便从标题中读取值
and then you need to create a custom FilterAttribute
to read the value from the Headers
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class ValidateHeaderAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]);
}
}
,然后在您的控制器方法中,将[ValidateAntiForgeryToken]
替换为[ValidateHeaderAntiForgeryToken]
and in your controller method, replace [ValidateAntiForgeryToken]
with [ValidateHeaderAntiForgeryToken]
但是,不必对数据进行字符串化,您可以使用
However, it is not necessary to stringify the data, and you can use
var data = {
startDate: $("#startdate").val(),
endDate: $("#enddate").val(),
__RequestVerificationToken: $('input[name=__RequestVerificationToken]').val()
};
$.ajax({
data: data,
....
});
并删除contentType
选项,使其使用默认的'application/x-www-form-urlencoded; charset=UTF-8'
and remove the contentType
option so it uses the default 'application/x-www-form-urlencoded; charset=UTF-8'
您尚未显示您的表单,假设它包含@Html.AntiForgeryToken()
和@Html.TextBoxFor(m => m.startDate)
和@Html.TextBoxFor(m => m.endDate)
,您可以使用name="startDate"
和name="endDate"
生成表单控件,那么您可以简单地使用
You have not shown your form, assuming it contains @Html.AntiForgeryToken()
and @Html.TextBoxFor(m => m.startDate)
and @Html.TextBoxFor(m => m.endDate)
to that you generate form controls with name="startDate"
and name="endDate"
, then you can simply use
var data = $('form').serialize();
$.ajax({
data: data,
....
});
序列化您所有的表单控件(包括令牌)
to serialize all your form controls including the token
这篇关于在ajax调用中不存在必需的反伪造表单字段"__RequestVerificationToken"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!