首页 > 解决方案 > 试图通过视图模型将表中的模型列表传递回控制器,但它总是为空?

问题描述

我一直遇到一个问题,当我尝试将 ViewModel 的一个字段发送回控制器时,它被传回为 null。我有一个这样设置的 ViewModel 文件:

 public class vmSCUMaster
    {
        public List<LockerDoorMaster> lockers { get; set; }
        public long? masterID { get; set; }
        public string masterName { get; set; }
    }

到目前为止,当我第一次将此 ViewModel 传递给 View 时,储物柜(列表)不为空,并且页面呈现正确的数据。但是,当我从视图提交表单时,储物柜始终为空。masterID 和 masterName 被发送回控制器就好了。在视图中,我在表格中显示储物柜的内容,并且用户可以选择向表格中添加更多物品。我希望这些添加的项目在传递回控制器时也附加到储物柜列表中。这是我在视图中的代码:

@using (Html.BeginForm("Create", "SCUMaster", new { area = "Branch" }, FormMethod.Post, new { id = "frmSCU", @enctype = "multipart/form-data", @class = "form-horizontal" }))

@Html.HiddenFor(model => model.masterID)
@Html.AntiForgeryToken()

<div class="panel-heading">
    <h4 class="panel-title" style="display: inline;">Lockers</h4>
    <div id="DivExport" class="pull-right"></div>
    <a href="#" onclick="$('#Add').modal('show');" class="btn btn-inverse btn-xs pull-right launch-modal" data-id="0" data-title="Add" data-toggle="modal"><i class="fa fa-plus"></i> Add New</a>
</div>
    <div class="table-responsive" id="tblMaster">
        <table id="default-datatable" class="table table table-bordered nowrap" cellspacing="0">
        <thead>
            <tr>
                <th>Hardware Name</th>
                <th>Display Name</th>
                <th>Door Type</th>
                <th>Status</th>
                <th>Enabled/Disabled</th>
                <th>ADA Compliant</th>
           </tr>
        </thead>
        <tfoot></tfoot>
        <tbody id="lockerDoors" class="form-group">
            @foreach (var item in Model.lockers)
            {
                <tr>
                    <td>
                         @Html.DisplayFor(modelItem => item.LockerDoorMasterID)
                    </td>
                    <td>
                         @Html.EditorFor(modelItem => item.LockerDoorNumber, new { htmlAttributes = new { @class = "form-control DisplayName" } })
                    </td>
                    <td class="DoorType">
                         @if (item.DoorType == 1)
                         {
                             <select>
                                 <option value="1" selected="selected">Customer</option>
                                 <option value="2">Merchant</option>
                             </select>
                         }
                         else
                         {
                             <select>
                                 <option value="1">Customer</option>
                                 <option value="2" selected="selected">Merchant</option>
                             </select>
                         }
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.LockerDoorStatu.LockerDoorStatusName, new { htmlAttributes = new { @class = "form-control Status" } })
                    </td>
                    <td>
                        @Html.CheckBoxFor(modelItem => item.IsActive, new { htmlAttributes = new { @class = "form-control IsEnabled" } })
                    </td>
                    <td>
                        @Html.CheckBoxFor(modelItem => item.IsADA, new { htmlAttributes = new { @class = "form-control IsADA" } })
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>
<br />
<br />
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <label id="btnSave" type="submit" onclick="submit();" class="btn btn-primary btn-success"><i class="fa fa-check"></i> Save</label>
        <a href="@Url.Action("Index", "SCUMaster")" class="btn btn-primary btn-danger"><i class="fa fa-close"></i> Cancel</a>
    </div>
</div>

这是我的脚本,它动态地将项目添加到我的表中:

function test() {
            $('#Add').modal('hide');
            var num = $("#number").val();
            var type = $("#type").val();
            var table = document.getElementById("lockers");
            if (num > 0) {
                for (var i = 0; i < num; i++) {
                    var rowCount = table.rows.length; 
                    var row = table.insertRow(rowCount);

                    var cell1 = row.insertCell(0);
                    var element1 = document.createElement("div");
                    element1.className = "form-group HardwareID"; 
                    cell1.appendChild(element1);
                    cell1.innerHTML = rowCount + 1; 

                    var cell2 = row.insertCell(1);
                    var element2 = document.createElement("input");
                    element2.type = "text";
                    element2.className = "form-group DisplayName";
                    element2.defaultValue = rowCount + 1; 
                    cell2.appendChild(element2);

                    var cell3 = row.insertCell(2);
                    var element3 = document.createElement("select");
                    if (type == 1) {
                        element3.innerHTML = "<option value='1' selected='selected'>Customer</option> <option value = '2'> Merchant</option>"
                    }
                    else {
                        element3.innerHTML = "<option value='1'>Customer</option> <option value = '2' selected='selected'> Merchant</option>"
                    }
                    element3.className = "form-group DoorType";
                    cell3.appendChild(element3);

                    var cell4 = row.insertCell(3);
                    var element4 = document.createElement("div");
                    element4.className = "form-group Status";
                    cell4.appendChild(element4);
                    cell4.innerHTML = "Closed"; 

                    var cell5 = row.insertCell(4);
                    var element5 = document.createElement("input");
                    element5.className = "form-group IsEnabled"; 
                    element5.type = "checkbox"; 
                    cell5.appendChild(element5);

                    var cell6 = row.insertCell(5); 
                    var element6 = document.createElement("input");
                    element6.className = "form-group IsADA"; 
                    element6.type = "checkbox"; 
                    cell6.appendChild(element6);
                }
            }
        }

现在我只是想通过调用常规表单 submit() 函数来提交。我也尝试使用 jquery/ajax 传递它,但这也没有奏效。这是我试图做的:

function submit() {
            var indexUrl = "/Branch/SCUMaster/Create";
            var list = [];
            $('#tblMaster tbody tr').each(function (index, ele) {
                var LockerDoorMaster = {
                    DoorType: $('.DoorType', this).val(),
                    LockerDoorStatus: 2,
                    IsActive: $('.IsEnabled', this).is(':checked'),
                    LockerDoorNumber: $('.DisplayName', this).val(),
                    LockerDoorMasterID: $('.HardwareID', this).val()
                }
                list.push(LockerDoorMaster);
            });
            var data = {
                masterID: $('#masterID').val(),
                masterName: $('#masterName').val(),
                lockers: list
            }

            $.ajax({
                type: 'POST',
                url: indexUrl,
                data: JSON.stringify(data),
                contentType: 'application/json',
                success: function (result) {
                    if (result.Message == "Error") {
                        warningMessage("Some thing went wrong please try again");
                    }
                    else if (result.Message == "success") {
                        window.location.href = window.location.href + "#save";
                        window.location.reload();
                    }
                },
                error: function (errormessage) {
                    warningMessage("Some thing went wrong please try again");
                }
            });
        }

对于这个问题这么长,我深表歉意,并提前感谢您的所有帮助!我已经被这个问题困扰了好几天了,所以感谢您的帮助!如果您需要更多信息,请告诉我。谢谢!

标签: javascriptc#htmljqueryasp.net-mvc

解决方案


如果您愿意走 jquery 路线,您可以利用已经存在的代码。

经过研究,我找到了这篇文章:pass-model-to-controller-action-using-ajax

使用提到的 [FromBody] 属性。我用你当前的实现对此进行了测试,它似乎立即解决了这个问题。

如果这不起作用,我还使用 $post 语法进行了测试,该语法无需字符串化即可工作。

$.post(indexUrl, data, function (response) {
//code to execute
});

推荐阅读