所需的防伪表单字段 "__RequestVerificationToken" 不存在。

4

这对我来说又是一个难题,我希望我的网站保持跨站攻击的保护。我正在使用asp.net mvc 5通过Ajax请求开发主/从表单。所以,为了创建一个条目,我必须通过Ajax请求的过程,如下:

$.ajax({
        url: '/Sales/Create',
        data: JSON.stringify(salesmain),
        type: 'POST',
        contentType: 'application/json;',
        dataType: 'json',
        success: function (result) {

            if (result.Success == "1") {
                window.location.href = "/Sales/index";
            }
            else {
                alert(result.ex);
            }
        }
    });

现在,它没有导航到Sales控制器中的Create操作,因为ajax请求上说,在此之前,它抛出了以下异常:

所需的防伪表单字段“__RequestVerificationToken”不存在。

我在谷歌上搜索了很多但仍然没有成功,这就是为什么我来到这里的原因。我读了一些博客,其中提到使用jquery获取隐藏的__RequestVerificationToken字段并将其附加到表单值中,将JSON.stringify(salesmain)封装在函数中,就可以解决问题:

$.ajax({
.
.
addRequestVerificationToken(JSON.stringify(salesmain))

并且这个函数:

function addRequestVerificationToken(data) {
data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
return data;
};

此外,我已经有以下代码结构:

@using (Html.BeginForm())
{
  @Html.AntiForgeryToken()
  .
  .

并且在执行“创建(Create)”操作之前的属性:

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Create([Bind(Include = "SalesId,ReferenceNo,SalesDate,SalesPerson")] SalesMain salesMain)
{
.
.

我还在使用jQuery 1.5版本,可能它是罪魁祸首,如果不是的话,我应该怎么做来解决这个问题?非常感谢您的帮助,谢谢!


salesmain(在 data: JSON.stringify(salesmain), 中)是什么?为什么不使用 data: $('form').serialize() 来序列化包括令牌在内的表单? - user3559349
先生,salesmain是一个JavaScript变量,以下是我在从表单中获取其值之前声明它的方式:var salesmain = { "SalesId": "", "ReferenceNo": "", "SalesDate": "", "SalesPerson": "", "SalesSubs": [] }; - Bilal Ahmed
2
但是如果你有一个表单(并且已经正确生成视图),那么只需使用data: $('form').serialize(),并删除contentType:'application / json;'。但是当您只是使用window.location.href ="/Sales/index";进行重定向时,为什么还要使用ajax呢? - user3559349
太棒了,我移除了contentType: 'application/json',错误消失了。你能否在下面解释一下,让我标记它为答案?实际上,当我遇到一些有经验的人时,感觉非常荣幸。 - Bilal Ahmed
1个回答

12

你的addRequestVerificationToken()函数没有添加令牌,因为你已经将数据字符串化了(它不再是JavaScript对象,所以data.__RequestVerificationToken = $(...)无效)。

你可以通过改变代码来使其工作:

data: JSON.stringify(addRequestVerificationToken(salesmain)),

然而这是不必要的,因为您不需要将数据转换为字符串。相反,删除 contentType: 'application/json;', 选项,以便使用默认的 application/x-www-form-urlencoded; charset=UTF-8' 并使用。

data: addRequestVerificationToken(salesmain),

或者更好的方法是,如果您使用HtmlHelper方法正确生成了视图,并且您的输入包含正确的名称属性(name="SalesId"name="ReferenceNo"等),那么您可以简单地使用
data: $('form').serialize(),`

这将正确地序列化您表单中的所有输入,包括令牌。


你真的很棒,非常感谢你 :) - Bilal Ahmed
1
我昨天开始就一直在寻找解决方案。无论我做了什么,'application/json' 都不能为我解决问题。然而 'application/x-www-form-urlencoded; charset=UTF-8' 却是完美的解决方法。非常感谢。 - Ashi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接