AntiforgeryToken 适用于一种形式,在部分视图 MVC 中适用于第二种形式

AntiforgeryToken works for one form and fails for 2nd form in partialview MVC

所以我有一个 partialview,里面有 2 个表格,如下所示:

@using (Html.BeginForm("AddAlbum", "Admin", FormMethod.Post, htmlAttributes: new { id = "frmAlbumAdd", novalidate = "novalidate", autocomplete = "off" }))
{
    @Html.AntiForgeryToken()
    <!--some controls and submit button-->
}
.....
.....
@using (Html.BeginForm("UploadImages", "Admin", FormMethod.Post, htmlAttributes: new { id = "frmUploadImages", novalidate = "novalidate", autocomplete = "off", enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    <!--some controls and submit button-->
}

我正在对 Admin controller 执行 ajax post,如下所示:

[HttpPost]
[ValidateAntiForgeryToken]//This works well
public JsonResult AddAlbum(AlbumDataModel model)
{
    //perform some task and return result
}

[HttpPost]
[ValidateAntiForgeryToken]//This results in Error
public JsonResult UploadImages([Bind(Prefix = "UIAModel")] UploadImageAlbum model)
{
    //perform some task and return result
}

我在第二次提交表单时遇到的错误是 "The required anti-forgery form field \"__RequestVerificationToken\" is not present."

根据这个 post in SO 我们可以分别为不同的 forms 设置 antiforgerytokens。但是我不确定为什么这是错误的。

我还尝试在 Layout 中添加 @Html.AntiForgeryToken(),其中 partialviews 加载并将其从 forms 中排除,并在 ajaxSetup 下方发送 AntiForgeryToken 但即使那样也没用。

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    var verificationToken = $("meta[name='__RequestVerificationToken']").attr('content');
    if (verificationToken) {
        jqXHR.setRequestHeader("X-Request-Verification-Token", verificationToken);
    }
});

我该如何解决这个问题?这里到底发生了什么?


更新:

我正在使用 ajax 到 post formdatacontroller,如下所示:

$.ajax({
      url: url,
      type: "POST",
      dataType: 'json',
      data: formData,
      processData: false,
      contentType: false,
      success: function (data) {

      }
});

我可以建议您尝试以下操作吗:

$("form").on("submit", function (event) {
        event.preventDefault();
        var form = $(this);
        $.ajax({
            url: form.attr('action'),
            type: "POST",
            data: form.serialize(),
            success: function (data) {
               //your implementation
            },
            error: function (jqXhr, textStatus, errorThrown) {
                alert("Error '" + jqXhr.status + "' (textStatus: '" + textStatus + "', errorThrown: '" + errorThrown + "')");
            },
            complete: function () {
               //your implementation
            }
        });
    });

这不使用 json 作为数据类型。你真的需要用json我喜欢你看看这个How can i supply an AntiForgeryToken when posting JSON data using $.ajax?

@Html.AntiForgeryToken() 使用 name="__RequestVerificationToken" 生成隐藏输入,以便获得您需要的值(对于第一种形式)

var verificationToken = $('#frmAlbumAdd [name=__RequestVerificationToken]').val();

然后您可以使用

将其附加到 FormData 对象
formData.append('__RequestVerificationToken', verificationToken);

但是,由于您使用的是 FormData,您可以简单地序列化所有表单控件,包括使用

的令牌和文件输入
var formdata = new FormData($('#frmAlbumAdd').get(0));

参考了解更多详情