【问题标题】:AJAX Posting ValidateAntiForgeryToken without Form to MVC Action MethodAJAX 将没有表单的 ValidateAntiForgeryToken 发布到 MVC 操作方法
【发布时间】:2013-07-25 08:04:03
【问题描述】:

我一直在查看如何在 SO 上执行此操作的示例,据我所知,我已经尝试了所有我能找到的示例,但到目前为止都没有成功。我已经尝试将一些实现更改为我的场景,但到目前为止这也失败了。

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

<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken()</form>

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

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

这一切都按预期工作,我得到了一个防伪令牌。我的实际发布代码是:

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"
    });
};

我的操作方法如下所示:

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

我一直在使用我一直在尝试的各种实现对此进行测试,并且响应始终是:

{"errorMessage":"The required anti-forgery form field \"__RequestVerificationToken\" is not present."}

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

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

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

【问题讨论】:

  • 我很困惑。如果您还没有看到这一点,并且您在下面的答案是其他人(我在 SO 上的其他答案中看到了该代码),您为什么要尝试回答您不理解的问题??
  • 属性不用分开...

标签: jquery asp.net-mvc json


【解决方案1】:

Cardboard 开发商再次罢工。

我所要做的就是删除:

contentType: "application/json; charset=utf-8"

通过这样做(这会改变发出请求的类型),以使实际数据属性的 Json 内容正确绑定到您的 T 模型类型 不要 @987654323 @数据。

【讨论】:

  • 救生员...谢谢!搜索了 2 天后,我只需要这条评论。非常感谢。
  • 太棒了! - 遵循了很多解决方案,但无济于事,但结果却是罪魁祸首,非常感谢!
  • 谢谢!浪费时间在这上面!!!一篇又一篇地阅读文章,只是没有得到任何地方。尝试了很多不同的东西,但几乎都提供了相同的最终结果,即在发布时包含验证令牌,并且直到我通过侥幸找到你的建议之前无法让它工作!还是不敢相信!谢谢分享!!
  • 为什么不能使用contentType: "application/json; charset=utf-8"?在什么情况下,我们可以使用contentType: "application/json; charset=utf-8",我们应该对数据进行字符串化?
  • 看来需要 contentType: "application/x-www-form-urlencoded" 才能找到 'form-field' 令牌
【解决方案2】:

(注意:我知道这与现有的并没有太大的不同)

我意识到这已经得到了回答,但我已经做了很多,并将我的答案添加到堆中。我的站点中没有表单,所以我必须想办法解决这个问题。对 stackoverflow 和一些博客的大量研究最终为我提供了所需的信息。

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

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()
}

然后,在所有 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
  }
});

最后,在控制器方面,这工作正常:

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

希望这会对处于同一条船上的其他人有所帮助。

【讨论】:

    【解决方案3】:

    验证被硬编码以查看表单数据。

    https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.WebPages/Helpers/AntiXsrf/AntiForgeryTokenStore.cs

        public AntiForgeryToken GetFormToken(HttpContextBase httpContext)
        {
            string value = httpContext.Request.Form[_config.FormFieldName];
    

    您可以通过遵循某种格式来模拟表单提交。为此,请参阅How to mimic an HTML form submission in a POST request?

    如果您愿意,您也可以制作自己的验证器。 How to POST JSON data to an Asp.Net MVC 2 app with ValidateAntiForgeryToken 解释了如何做到这一点。它适用于 MVC 2,但您可以从中汲取一些想法。

    【讨论】:

    • 当然,自定义验证器可能被视为矫枉过正。我只是解释问题的原因和两种可能的解决方案。您发布的答案几乎是我第一个链接中信息的最终结果。
    猜你喜欢
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2019-03-30
    • 2022-07-15
    • 1970-01-01
    • 2013-03-16
    • 2012-08-09
    相关资源
    最近更新 更多