在MVC5中使用AJAX调用

时间:2016-08-17 15:03:14

标签: javascript jquery asp.net ajax asp.net-mvc

我试图在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方法和错误部分是否正常?或者那里有任何缺失或额外的部分?

2 个答案:

答案 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一起使用时,必须将contentTypeFormData都设置为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>