C# 通过JSON.stringify在JSON post请求中传递AntiForgeryToken无效
我有下面的jQuery代码,它使用JSON.stringify将数据发布到ASP.NET MVC控制器类。没有防伪代币,一切正常。现在,当我开始在代码库中实现AntiForgeryToken时,它不起作用并抛出一个错误:所需的防伪表单字段“\uu RequestVerificationToken”不存在 HTMLC# 通过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() ....
<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提供的解决方案。我同意你的观点,并且一定会执行你提供的链接中建议的方法。