【问题标题】:My Action won't work with HTTP POST我的操作不适用于 HTTP POST
【发布时间】:2013-11-08 04:14:46
【问题描述】:

您好,我在尝试将数据从 js 文件传递​​到 MVC 控制器中的操作时遇到问题。这是我的控制器。

    [HttpPost]
    [CustomAuthorize(Roles.Administrator, Roles.ContextOwner, Roles.DataOwner, Roles.DataSteward)]
    public JsonResult SaveChangesOnGrid(int id, string json)
    {
        var codeViewModels = JsonConvert.DeserializeObject<CodeViewModel[]>(json);

        var error = string.Empty;
        CodeViewModel newViewModel = null;

        foreach (var viewModel in codeViewModels)
        {
            viewModel.CodeListId = id;
            if (ModelState.IsValid)
            {
                error = codeService.Validate(viewModel);

                if (string.IsNullOrEmpty(error))
                {
                    newViewModel = codeService.SaveToStage(viewModel);
                }
            }
            else
            {
                error = "Could not save";
            }
        }

        if (id > 0 && string.IsNullOrEmpty(error))
        {
            // notify
            var codeList = codeListService.GetCurrentCodeListById(id);
            notifyGroup.NotifyDataOwnerGroup(codeList);
        }

        return Json(new
        {
            error,
            newViewModel
        });
    }

当我使用 HTTPPOst 注释时,我再也无法使用它了。我正在尝试使用视图上的按钮访问操作。我尝试了 2 种不同的方法,但都不起作用。

<a id="review_btn" class="btn btn-primary" href='@Url.Action("SaveChangesOnGrid", "Code", new {id = Model.CodeListId })'>Submit for Review</a>

编辑:按钮的 HTML 输出是

<div class="btn-group offset10" style="margin-top: 20px; margin-bottom: 20px">
        <a id="review_btn" class="btn btn-primary" href='/ReferenceData.Web/Code/SaveChangesOnGrid/13'>Submit for Review</a>
</div>

在我的 JS 文件中,我有一个函数尝试将 JSon 数组传递给我的控制器操作 EDIT Ajax 更新:当按下按钮时,现在有一个内部服务器错误 Http 500。当我在开发人员工具中检查网络包时,它会显示带有 JSON 包的 HTTP 包

    function rowsToJson(obj) {
    var selRowIds = $("#CodeGrid").jqGrid('getGridParam', 'selarrrow');

    if (selRowIds.length > 0) {

        var rowData = jQuery('#CodeGrid').jqGrid('getRowData', selRowIds[0]);
        var selectedRowsData = [{ "Code": rowData.Code, "ParentCode": rowData.ParentId, "Name": rowData.Name, "Description": rowData.Description }];

        for (var i = 1; i < selRowIds.length; i++) {

            rowData = jQuery('#CodeGrid').jqGrid('getRowData', selRowIds[i]);

            selectedRowsData.push({ "CodeId": rowData.CodeId, "Code": rowData.Code, "ParentCode": rowData.ParentId, "Name": rowData.Name, "Description": rowData.Description });
        }

        $.ajax({
            url: window.g_baseUrl + 'Code/SaveChangesOnGrid',
            type: 'POST',
            data: JSON.stringify(selectedRowsData),
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            async: true,
            processData: false
        });

        //$(obj).attr('href', obj.href + "?json=" + JSON.stringify(selectedRowsData));
        return true;
    }
    else {
        alert("Please select a code");
        return false;
    }
};

$(function () {
    $('#review_btn').click(function () {
        if (confirm('These Selected Changes will be submitted for approval \n\n Are you sure you wish to proceed?')) {
            return rowsToJson(this);
        } else {
            $('#CodeGrid').jqGrid('resetSelection');
            return false;
        }
    });
});

您可以从我注释掉的内容中看到我尝试使用 AJAX 并将 JSON 作为字符串附加到 URL 的末尾。

使用 AJAX 并从按钮中删除 href 我收到错误 500。如果我在调试控制器时将 href 保留在其中,则 json 参数为空。

如果我使用 HTTPPost 注释将 JSON 数组附加到 URL 的末尾,则 json 参数为空。当我删除注释时,JSON 会通过,但是当我单步执行代码时,会抛出一个错误,告诉我涉及 JSON 和 Get 的安全问题

如果可能,我更喜欢使用 Ajax,因为它可以避免 URL 中的数据对用户可见。但我真的只是想让一些工作。

【问题讨论】:

  • 任何控制台错误?这个最终的 html 输出是什么: url: '@Url.Action("SaveChangesOnGrid", "CodeController", new {id = Model.CodeListId })',
  • @RealityDysfunction 您好刚刚添加了按钮的 HTML 输出,在我尝试使用 AJAX 调用时按下按钮之前没有控制台错误
  • 调试时,你的控制器代码中哪一行是抛出的错误?
  • console.log(JSON.stringify(selectedRowsData)) 向您展示了什么?它与您的操作签名匹配吗?
  • @Jasen stringify 的输出是 [{"Code":"BRA","ParentCode":" ","Name":"BRA","Description":"Brazil"}]。使用 AJAX 代码不会到达控制器。控制器中的错误来自使用 GET,我想在阅读下面的答案后避免这种情况

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


【解决方案1】:

首先,忘记使用 GET,它看起来很丑,如果 JSON 变得太大,可能会失败。 看看这里是如何设置动作的:

Calling WebMethod returning IList<T> from Jquery Ajax with NHibernate And MVC

这里:

http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

试着按照上面的例子简化一下。

我相信这里需要 JSON.Stringify。现在还要删除角色注释,直到您的代码正常运行。

【讨论】:

    【解决方案2】:

    您发布的数据与您的操作签名不匹配。您可以在调试控制台的 PreviewResponse 选项卡上查看异常详细信息。

    你的动作签名:

    [HttpPost]
    public JsonResult SaveChangesOnGrid(int id, string json)
    

    您的 POST 正在发送:

    var selectedRowsData = [{ "Code": rowData.Code, "ParentCode": rowData.ParentId, "Name": rowData.Name, "Description": rowData.Description }];
    selectedRowsData.push({ "CodeId": rowData.CodeId, "Code": rowData.Code, "ParentCode": rowData.ParentId, "Name": rowData.Name, "Description": rowData.Description });
    
    $.ajax({
        ...
        data: JSON.stringify(selectedRowsData)
    });
    

    预期的是:

    var selectedRowsData = [{ "Code": "", "ParentCode": "", "Name": "", "Description": "" }];
    
    $.ajax({
        ...
        data: JSON.stringify({ "id": "1", "json": JSON.stringify(selectedRowsData) });
    });
    

    这可能不是你想要的所以......

    试试这个

    让框架做绑定和反序列化。

    var selectedRowsData = [];
    for (var i = 1; i < selRowIds.length; i++) {
        rowData = jQuery('#CodeGrid').jqGrid('getRowData', selRowIds[i]);
        selectedRowsData.push({ "CodeId": rowData.CodeId, "Code": rowData.Code, "ParentCode": rowData.ParentId, "Name": rowData.Name, "Description": rowData.Description });
    }
    
    $.ajax({
        ...
        data: JSON.stringify(selectedRowsData)
    });
    

    现在创建一个反映您的 JSON 对象的模型。 (你的CodeViewModel?)

    public class Country
    {
        public int CodeId { get; set; }
        public string Code { get; set; }
        public string ParentCode { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
    

    更改动作签名

    [HttpPost]
    public JsonResult SaveChangesOnGrid(Country[] codes)
    

    ...然后忘记手动反序列化数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      • 2021-04-27
      • 2014-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多