来自AJAX调用的ValidateAntiForgeryToken失败

时间:2014-12-10 16:18:45

标签: javascript jquery ajax model-view-controller antiforgerytoken

编辑:我还尝试了一些其他内容..请参阅此问题的最后更新

我试图通过AJAX将一些数据和AntiForgeryToken从我的MVC应用程序中的页面传递给控制器​​。这不是我这样做的唯一地方,但这是第一个不能正常工作的地方。

我的代码的java方面是:

var dirtyFields = [];

$('.DirtyField').each(function () {
    var newValue;

    if ($(this).is('select'))
        newValue = $(this).val();
    else if ($(this).is('input[type="text"]'))
        newValue = $(this).val();
    else
        newValue = ($(this).is(':checked')) ? 'true' : 'false';

    dirtyFields.push({
        FieldName: $(this).attr('name'),
        OldValue: $(this).attr('data-oldvalue'),
        NewValue: newValue
    });
});

var token = $("#__AjaxAntiForgeryForm input").val();
var dataObject =
    {
        __RequestVerificationToken: token,
        MaintUserId: $('#HiddenMaintUserID').val(),
        ChangedFields: dirtyFields
    };

$.ajax({
    url: '@Url.Action("SaveDataAction", "SomeController")',
    type: 'POST',
    contentType: 'json',
    data: dataObject,
    error: function (jqXHR, textStatus, errorThrown) {
        console.log(jqXHR);
        console.log(textStatus);
        console.log(errorThrown);
    }
}).done(function (result) {
    if (result.Success == 'true') {
        alert("User information was updated successfully!");
    }
    else {
        alert("Update failed!");
    }

在我的应用程序的控制器端是:

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult SaveDataAction(SaveDataHelper dataObject)
{
    return Json(new { Success = "true" }, JsonRequestBehavior.DenyGet);
}

SaveDataHelper的定义是:

public class SaveDataHelper
{
    public int MaintUserID { get; set; }
    public List<DataItemHelper> ChangedFields { get; set; }
}

public class DataItemHelper
{
    public string FieldName { get; set; }
    public string OldValue  { get; set; }
    public string NewValue  { get; set; }
}

打破我的javascript,在ajax调用时,变量dataObject包含以下内容:

Object {__RequestVerificationToken: "Long-string-of-characters", MaintUserId: "9", ChangedFields: Array[1]}

ChangedFields包含以下内容:

0: Object
    FieldName: "MiddleName"
    NewValue: ""
    OldValue: "S"

当我收到错误时,我会查看控制台中的jqXHR,并在responseText的顶部找到它:

[HttpAntiForgeryException (0x80004005): The required anti-forgery form field &quot;__RequestVerificationToken&quot; is not present.]

此代码与我的应用程序中的代码类似。这里唯一的区别是我在dataObject中传递一个数组(这是我第一次需要这样做)。

有什么建议吗?

编辑:由于有关AntiForgery表格的问题,我(在Chrome中)访问了View Page Source并从那里粘贴了几行:

<form action="/Admin/UserMaint/9" id="__AjaxAntiForgeryForm" method="post"><input name="__RequestVerificationToken" type="hidden" value="long-string-of-charaacters-here" /></form><!DOCTYPE html>
<html>
<head>

所以__AjaxAntiForgeryForm是我页面上的第一件事..甚至在html标签之前。

以下是我的视图中创建的部分:

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

- 编辑12/10/2014 @美国东部时间下午2:31 -

在经历了一些针对此的评论之后,尤其是@Pointy的评论之后,我尝试了#34;展平&#34;我的数据。我用以下内容替换了我的dataObject逻辑:

var dataObject = {
    __RequestVerificationToken: token,
    UserId: '@Model.UserId',
    Field1Dirty: ($('#FieldID').hasClass('DirtyField')) ? 1 : 0,
    Field1Old: $('#FieldID').attr('data-oldvalue'),
    Field1New: $('#FieldID').val(),
    -- etc --
};

然而,即使数据完全平坦,我仍然看到数据作为Request Payload传递,而我仍然没有在控制器中得到任何东西。

- 编辑12/10/2014 @美国东部时间下午3:23 -

嗯..现在我完全失去了。我编写了我的代码:

var dataObject = {
    UserId: '9'
};

它仍然以请求有效载荷的形式发送。我不知道下一步该尝试什么。

1 个答案:

答案 0 :(得分:1)

您的传出$.ajax()来电已使用contentType属性进行编码。这会影响请求的内容类型,而不会影响响应。

我没有在jQuery源代码中找到影响HTTP请求的位置和方式。