我试图在MVC5项目中使用AJAX调用,就像在网上有很多类似的例子,但每次都有错误,例如antiforgerytoken,500等等。我正在寻找一个适当的AJAX调用方法,使用Controller Action方法具有所有必需的属性,并从View到Controller Action发送模型数据。以下是我使用的方法:
查看:
@using (Html.BeginForm("Insert", "Account", FormMethod.Post, new { id = "frmRegister" }))
{
@Html.AntiForgeryToken()
//code omitted for brevity
}
<script>
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
return data;
};
$('form').submit(function (event) {
event.preventDefault();
//var formdata = JSON.stringify(@Model); //NOT WORKING???
var formdata = new FormData($('#frmRegister').get(0));
//var token = $('[name=__RequestVerificationToken]').val(); //I also tried to use this instead of "AddAntiForgeryToken" method but I encounter another error
$.ajax({
type: "POST",
url: "/Account/Insert",
data: AddAntiForgeryToken({ model: formdata }),
//data: { data: formdata, __RequestVerificationToken: token },
//contentType: "application/json",
processData: false,
contentType: false,
datatype: "json",
success: function (data) {
$('#result').html(data);
}
});
});
</script>
控制器:由于反伪造或类似问题,代码无法访问此Action方法。
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public JsonResult Insert(RegisterViewModel model)
{
try
{
//...
//code omitted for brevity
}
}
我只需要一个适当的AJAX和Action方法,可以用于MVC5中的CRUD操作。任何帮助将不胜感激。
更新:以下是我需要澄清的一些要点:
1)我们没有使用&#34; __ RequestVerificationToken&#34;我不确定我们是否正确地将它发送给控制器(它似乎是Firebug请求标题中的cookie,但我不确定它是否正常)。任何的想法?
2)我应该使用var formdata = new FormData($(&#39;#frmRegister&#39;)。get(0));当我上传文件?
3)为什么我必须避免在这种情况下使用processData和contentType?
4)AJAX方法的Controller方法和错误部分是否正常?或者那里有任何缺失或额外的部分?
答案 0 :(得分:5)
如果视图中的模型为RegisterViewModel
并且您使用强类型HtmlHelper
方法正确生成了表单控件,则可以正确使用new FormData($('#frmRegister').get(0))
或$('#frmRegister').serialize()
发送<form>
标记内所有表单控件的值,包括令牌,并且不必再次添加令牌。
如果您的表单不包含文件输入,则代码应为
$('form').submit(function (event) {
event.preventDefault();
var formData = $('#frmRegister').serialize();
$.ajax({
type: "POST",
url: '@Url.Action("Insert", "Account")', // do not hard code your url's
data: formData,
datatype: "json", // refer notes below
success: function (data) {
$('#result').html(data);
}
});
});
或更简单
$.post('@Url.Action("Insert", "Account")', $('#frmRegister').serialize(), function(data) {
$('#result').html(data);
});
如果您要上传文件,则需要使用FormData
并且代码需要(请参阅this answer和
$('form').submit(function (event) {
event.preventDefault();
var formData = new FormData($('#frmRegister').get(0));
$.ajax({
type: "POST",
url: '@Url.Action("Insert", "Account")',
data: formData,
processData: false,
contentType: false,
datatype: "json", // refer notes below
success: function (data) {
$('#result').html(data);
}
});
});
请注意,在将jQuery与processData
一起使用时,必须将contentType
和FormData
都设置为false。
如果你得到一个500(Internal Server Error)
,它几乎总是意味着你的控制器方法抛出异常。在您的情况下,我怀疑这是因为您的方法返回了部分视图(正如您$('#result').html(data);
回调中的success
代码行所示),但您已指定返回类型应为{{ 1}}(您使用json
选项)。请注意,没有必要指定datatype: "json",
选项(dataType
方法将在未指定的情况下解决)
如果这不是.ajax()
的原因,那么您需要调试代码以确定导致预期的原因。您可以使用浏览器开发人员工具来协助该过程。打开网络选项卡,运行该功能,(将突出显示该功能的名称),单击它,然后检查响应。它将包括投掷的详细信息。
答案 1 :(得分:1)
contentType应为application/x-www-form-urlencoded
试试此代码
<script>
$('form').submit(function (event) {
event.preventDefault();
$.ajax({
method: "POST",
url: "/Account/Insert",
data: $(this).serialize(),
contentType:"application/x-www-form-urlencoded",
success: function (data) {
$('#result').html(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
</script>