在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, .... });
序列化所有表单控件,包括令牌