【发布时间】:2015-02-08 22:25:14
【问题描述】:
编辑:我已经尝试了更多的东西.. 看到这个问题的结尾更新
我正在尝试通过 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 "__RequestVerificationToken" is not present.]
此代码类似于我的应用程序中的所有代码。这里唯一的区别是我在 dataObject 中传递了一个数组(这是我第一次需要这样做)。
有什么建议吗?
编辑:由于关于 AntiForgery 表单的问题 .. 我(在 Chrome 中)去了查看页面源并从那里粘贴了 TOP 几行:
<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 PM EST --
在浏览了一些为此制作的 cmets,尤其是 @Pointy 的 cmets 之后,我尝试“扁平化”我的数据。我已将我的 dataObject 逻辑替换为以下内容:
var dataObject = {
__RequestVerificationToken: token,
UserId: '@Model.UserId',
Field1Dirty: ($('#FieldID').hasClass('DirtyField')) ? 1 : 0,
Field1Old: $('#FieldID').attr('data-oldvalue'),
Field1New: $('#FieldID').val(),
-- etc --
};
但是,即使使用完全平坦的数据,我仍然看到作为请求有效负载传递的数据,并且我在控制器中仍然没有得到任何信息。
-- 编辑 12/10/2014 @ 3:23 PM EST --
嗯..现在我完全迷路了。我将代码编辑为:
var dataObject = {
UserId: '9'
};
它仍然作为请求有效负载发送。我不知道接下来要尝试什么。
【问题讨论】:
-
您应该能够使用浏览器的开发人员工具准确查看 HTTP 请求的样子,以便验证您的页面是否发送正确的请求。
-
请注意,
var token = $("#__AjaxAntiForgeryForm input").val();将获取表单中第一个<input>元素的值。这真的是正确的做法吗?第一个<input>是其中包含您的安全令牌的那个吗? -
另外,正如@Pointy 所指出的,这将是获取其价值的正确方法:
$("input[name=__RequestVerificationToken]").val(); -
您是否检查过以确保传出的 HTTP 请求看起来正常?
-
好吧,现在我看看您设置参数的方式,我认为这就是问题所在。由于这些嵌套对象,jQuery 无法将您的“dataObject”转换为查询字符串。
标签: javascript jquery ajax model-view-controller antiforgerytoken