【问题标题】:AntiforgeryToken works for one form and fails for 2nd form in partialview MVCAntiforgeryToken 适用于一种形式,但在 partialview MVC 中适用于第二种形式
【发布时间】:2016-02-03 23:24:36
【问题描述】:

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

@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 controllerajax 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
}

我在第二次提交表单时遇到的错误是 “所需的防伪表单字段 \"__RequestVerificationToken\" 不存在。”

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

我也尝试在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);
    }
});

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


更新:

我正在使用ajaxformdata 发布到controller,如下所示:

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

      }
});

【问题讨论】:

  • 你能添加创建 ajax 请求的 javascript 吗?
  • @RobbertBrussaard.. 更新问题。请检查并告诉我...
  • 你是如何产生formdata的值的?如果您使用var formdata = new FormData($('#frmUploadImages').get(0));,那么包括令牌在内的所有内容都会被序列化,并且您不需要$.ajaxPrefilter() 函数(有关更多详细信息,请参阅this answer
  • 您检查过var verificationToken = $("meta[name='__RequestVerificationToken']").attr('content'); 实际返回的内容吗? - 我怀疑是undefined
  • 嗯,一定错过了您之前的消息。需要一些睡眠,但会在早上这样做:)

标签: ajax asp.net-mvc asp.net-mvc-4 antiforgerytoken


【解决方案1】:

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

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

然后您可以将其附加到 FormData 对象使用

formData.append('__RequestVerificationToken', verificationToken);

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

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

更多详情请参考this answer

【讨论】:

    【解决方案2】:

    我可以建议您尝试以下方法吗:

    $("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?

    【讨论】:

    • 据我所知,dataType 基本上是考虑我们从服务器接收到什么类型的数据。但是这个问题是关于发送部分的。我希望不会有太大影响。还是让我试一试,让你知道..
    猜你喜欢
    • 1970-01-01
    • 2020-10-04
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    相关资源
    最近更新 更多