C# 通过JSON.stringify在JSON post请求中传递AntiForgeryToken无效

C# 通过JSON.stringify在JSON post请求中传递AntiForgeryToken无效,c#,asp.net-mvc-5,csrf-protection,antiforgerytoken,C#,Asp.net Mvc 5,Csrf Protection,Antiforgerytoken,我有下面的jQuery代码,它使用JSON.stringify将数据发布到ASP.NET MVC控制器类。没有防伪代币,一切正常。现在,当我开始在代码库中实现AntiForgeryToken时,它不起作用并抛出一个错误:所需的防伪表单字段“\uu RequestVerificationToken”不存在 HTML <form action="javascript: void(0)" id="frmMain"> @Html.AntiForgeryToken() ....

我有下面的jQuery代码,它使用JSON.stringify将数据发布到ASP.NET MVC控制器类。没有防伪代币,一切正常。现在,当我开始在代码库中实现AntiForgeryToken时,它不起作用并抛出一个错误:所需的防伪表单字段“\uu RequestVerificationToken”不存在

HTML

<form action="javascript: void(0)" id="frmMain">
    @Html.AntiForgeryToken()
    ....
</form>
TestController.cs

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel)
{
  if (!ModelState.IsValid)
  {
        return Json(new { success = false });
  }
}
[HttpPost]
[ValidateHeaderAntiForgeryToken]
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel)
{
  if (!ModelState.IsValid)
  {
        return Json(new { success = false });
  }
}

function saveDetails() {              
    var testViewModel = {};
    testViewModel.ArticleType = $("#SubType").val()
    testViewModel.PublishedDate = $("#publishDate").val();
    var token = $('#frmMain input[name=__RequestVerificationToken]').val();

    var languages = [];
    $.each($('#language').val(), function (index, value) {
        var languageContent = {};
        languageContent.Language = value;
        languageContent.Author = $("#author-" + value).val();
        languageContent.TeaserText = $("#teaser-" + value).val();
        languageContent.body = $("#content-" + value).val();
        languageContent.Title = $("#title-" + value).val();
        languages.push(languageContent);
    });
    testViewModel.LanguageContent = languages;
    testViewModel.Author = testViewModel.LanguageContent[0].Author;
    testViewModel.ArticleId = aId;


    $.ajax({
        type: "POST",
        url: "@Url.Action("SaveDetails", "Test")",        
        headers: {
                "__RequestVerificationToken": token
        },
        data: JSON.stringify(testViewModel),
        cache: false,
        success: function (data) {
            var url = "@Url.Action("SiteDetails", "Test")";
            window.location.href = url + "?ArticleId=" + aId;
        }
    });
}

这里有人能帮我解决这个问题吗?

我添加了另一个过滤器:

namespace TestDetails.Controllers
{
    [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"]);
        }
    }
}
TestController.cs

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel)
{
  if (!ModelState.IsValid)
  {
        return Json(new { success = false });
  }
}
[HttpPost]
[ValidateHeaderAntiForgeryToken]
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel)
{
  if (!ModelState.IsValid)
  {
        return Json(new { success = false });
  }
}

function saveDetails() {              
    var testViewModel = {};
    testViewModel.ArticleType = $("#SubType").val()
    testViewModel.PublishedDate = $("#publishDate").val();
    var token = $('#frmMain input[name=__RequestVerificationToken]').val();

    var languages = [];
    $.each($('#language').val(), function (index, value) {
        var languageContent = {};
        languageContent.Language = value;
        languageContent.Author = $("#author-" + value).val();
        languageContent.TeaserText = $("#teaser-" + value).val();
        languageContent.body = $("#content-" + value).val();
        languageContent.Title = $("#title-" + value).val();
        languages.push(languageContent);
    });
    testViewModel.LanguageContent = languages;
    testViewModel.Author = testViewModel.LanguageContent[0].Author;
    testViewModel.ArticleId = aId;


    $.ajax({
        type: "POST",
        url: "@Url.Action("SaveDetails", "Test")",        
        headers: {
                "__RequestVerificationToken": token
        },
        data: JSON.stringify(testViewModel),
        cache: false,
        success: function (data) {
            var url = "@Url.Action("SiteDetails", "Test")";
            window.location.href = url + "?ArticleId=" + aId;
        }
    });
}

现在工作正常。

删除json和stringify,然后将数据作为isRefer发布。但是,您为集合生成带有
id
属性的表单控件这一事实表明您的做法完全错误。而使用ajax提交for然后重定向的事实是毫无意义的。只需正确生成视图(请参阅为集合生成表单控件,或者动态添加控件),并在POST方法中进行正常的提交和重定向。感谢Stephen提供的解决方案。我同意你的观点,并且一定会执行你提供的链接中建议的方法。