AJAX将没有表单的ValidateAntiForgeryToken发布到MVC操作方法

Jam*_*mer 21 asp.net-mvc jquery json

我一直在寻找如何在SO上做到这一点的例子,据我所知,我已经尝试了所有可以找到但迄今为止没有成功的例子.我已经尝试将一些实现改为我的场景,但迄今为止也失败了.

我在_layout.cshtml的页面上有这个,所以我总是有一个令牌:

<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken()</form>
Run Code Online (Sandbox Code Playgroud)

我的JavaScript utils文件中也有这个方法:

AddAntiForgeryToken = function (data) {
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
    return data;
};
Run Code Online (Sandbox Code Playgroud)

这一切都按预期工作,我得到一个防伪标记.我的实际发布代码是:

myPage.saveData = function() {
    var saveUrl = '/exercises/PostData';

    var myData = JSON.stringify(myPage.contextsArrays);

    $.ajax({
        type: 'POST',
        async: false,
        url: saveUrl,
        data: AddAntiForgeryToken({ myResults: myData }),
        success: function () {
            alert('saved');
        },
        dataType: 'json',
        contentType: "application/json; charset=utf-8"
    });
};
Run Code Online (Sandbox Code Playgroud)

我的动作方法如下所示:

    [HttpPost, ValidateAntiForgeryToken, JsonExceptionFilter]
    public JsonResult PostData(List<ResultsDc> myResults)
    {
        return Json(_apiClient.SubmitResults(myResults));
    }
Run Code Online (Sandbox Code Playgroud)

我一直在尝试使用我一直在尝试的各种实现,并且响应总是:

{"errorMessage":"The required anti-forgery form field \"__RequestVerificationToken\" is not present."}
Run Code Online (Sandbox Code Playgroud)

我不是发布一个表单,它只是一个数据数组,但检查实际发布的数据Json看起来不正确(它全部编码)但是__RequestVerificationToken参数名称在那里,并且令牌值也存在.

我现在对这一切感到很困惑,无法找到发送令牌的正确方法,以便调用我的MVC操作.如果我删除该ValidateAntiForgeryToken属性并将JSON.stringify(myPage.contextsArrays);数据作为json看起来正确(未编码)并且映射正常.

如何在没有表格的情况下正确发布此令牌?

Jam*_*mer 32

纸板开发商再次罢工.

我所要做的就是删除:

contentType: "application/json; charset=utf-8"
Run Code Online (Sandbox Code Playgroud)

通过这样做(它改变了发布请求的类型),获取实际数据属性的Json内容以正确绑定到您的T模型类型而不是 JSON.stringify()数据.


ESD*_*tor 14

(注意:我知道这与已经存在的内容并没有太大的不同)

我意识到这已经得到了回答,但我已经完成了这一点,并将我的答案添加到堆中.我的网站上没有表格,所以我不得不想办法处理这个问题.关于stackoverflow和一些博客的很多研究终于给了我需要的信息.

首先,这是我的"主"页面(MVC Razor)顶部的代码:

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()
}
Run Code Online (Sandbox Code Playgroud)

然后,在所有ajax调用(jQuery)中,我这样开始:

var token = $("#__AjaxAntiForgeryForm input").val();
var dataObject = {
  __RequestVerificationToken: token,
  myData: "whatever"
};

$.ajax({
  url: '@Url.Action("action", "controller")',
  type: 'POST',
  dataType: 'json',
  data: dataObject,
  error: function (jqXHR, textStatus, errorThrown) {
    console.log("ERROR!");
  },
  success: function (data) {
    //whatever
  }
});
Run Code Online (Sandbox Code Playgroud)

最后,在Controller方面,这很好用:

public class controllerController : Controller
{
    [HttpPost]
    [ValidateAntiForgeryToken]
    public JsonResult action (myModel myData)
    {
        return Json(new { Success = "true" }, JsonRequestBehavior.DenyGet);
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助其他人在同一条船上.