在ajax调用中不存在所需的防伪表单字段“__RequestVerificationToken”

我在控制器中有以下方法

[HttpPost] [Authorize(Roles ="Klient")] [ValidateAntiForgeryToken] public ActionResult GetAvaiableHouses(DateTime startDate, DateTime endDate) { Session.Remove("Reservation"); IEnumerable  avaiableHouses = repository.GetAllNamesAvaiableHouses(repository.GetAvaiableHousesInTerm(startDate, endDate)); List houses = new List(); 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脚本来调用此方法

 $(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); } }); }); }); 

这是按钮的一部分,用于调用此脚本

 

我添加了附加参数

 '",__RequestVerificationToken:"' + $('input[name=__RequestVerificationToken]').val() 

进入ajax脚本但在执行期间我仍然收到错误

,__ RequestVerificationToken不存在。

可能是什么原因?

如果你使用contentType: 'application/json对字符串进行字符串化,那么将标记添加到ajax标题中,例如

 var headers = { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val() }; $.ajax({ headers: headers, data: ... // remove the token from your existing implementation .... }); 

然后你需要创建一个自定义FilterAttribute来读取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]

但是,没有必要对数据进行字符串化,您可以使用

 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' 'application/x-www-form-urlencoded; charset=UTF-8'

您没有显示您的表单,假设它包含@Html.AntiForgeryToken()@Html.TextBoxFor(m => m.startDate)@Html.TextBoxFor(m => m.endDate) ,您生成表单控件的name="startDate"name="endDate" ,那么你可以简单地使用

 var data = $('form').serialize(); $.ajax({ data: data, .... }); 

序列化所有表单控件,包括令牌