强类型视图在ViewModel中发布空集合

时间:2015-08-10 15:46:48

标签: c# model-view-controller

 public class UserSettingsViewModel
{
    [Display(Name="Kullanıcılar")]
    public List<UserFormViewModel> Users { get; set; }

    [Display(Name = "Roller")]
    public IEnumerable<SYS_ROLE> SYS_ROLE { get; set; }

    public RoleEditViewModel CurrentRoleEdit { get; set; }
}

public class RoleEditViewModel
{
    public int RoleID { get; set; }
    [Display(Name="Rol"),Required(ErrorMessage="Rol boş geçilemez.")]
    public string RoleName { get; set; }

    public List<RoleRightModel> RoleRights { get; set; }
}

public class RoleRightModel
{
    public int ID { get; set; }
    [Display(Name = "Tanım")]
    public string NAME_ { get; set; }
    [Display(Name = "Açıklama")]
    public string DESC_ { get; set; }
    public bool CHECKED { get; set; }
}

在View中使用UserSettingViewModel的人

    @model PlusNet.Models.ViewModels.UserSettingsViewModel
//some code here
 @Html.Partial("_RoleEdit", Model.CurrentRoleEdit)

部分视图渲染正确。这是_RoleEdit局部视图源

@model PlusNet.Models.ViewModels.RoleEditViewModel                           ROL                               @using(Html.BeginForm(“RoleEdit”,“Settings”))             {                 @ Html.HiddenFor(model =&gt; model.RoleID)

            <div class="form-group mt-lg">
                <label class="col-sm-3 control-label">@Html.DisplayNameFor(model => model.RoleName)</label>
                <div class="col-sm-9">
                    @*<input type="text" id="txt_role" class="form-control" />*@
                    @Html.TextBoxFor(model => model.RoleName, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.RoleName)

                </div>
            </div>

            <table class="table table-bordered table-striped mb-none deftable-nav" id="rightsgrid">
                <thead>
                    <tr>
                        <th>@Html.DisplayNameFor(model => model.RoleRights.FirstOrDefault().NAME_)</th>
                        <th>@Html.DisplayNameFor(model => model.RoleRights.FirstOrDefault().DESC_)</th>
                        <th class="center no-sort">İşlem</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model.RoleRights)
                    {
                        <tr class="tablerow" data-id="@item.ID">
                            <td>@item.NAME_</td>
                            <td>@item.DESC_</td>
                            <td class="center">
                                <div class="checkboxdiv">
                                    <div class="checkbox-custom checkbox-primary">
                                        @*<input type="checkbox" checked="" class="chck_right">*@
                                        @Html.CheckBox("CHECKED")
                                        <label for="chck_right"></label>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    }
                </tbody>
            </table>


            <footer class="panel-footer">
                <div class="row">
                    <div class="col-md-12 text-right">
                        <input type="hidden" id="hidden_roleid" value="0" />
                        <button class="btn btn-primary">Kaydet</button>
                        <button class="btn btn-default modal-dismiss" id="btn_modalrole_cancel">İptal</button>
                    </div>
                </div>
            </footer>
        }
    </div>
</section>

`

它生成得很好而且不是空的

@foreach(Model.RoleRights中的var项目)

表单提交并触发控制器操作

public ActionResult RoleEdit(RoleEditViewModel vm)

vm对象已满。除RoleRights集合外。它的总是空的。怎么了?我已经尝试过editortemplate,没有html.checkbox,html.action,viewdatadictionary ...无论如何收集来自post方法的null。其他viewmodel属性已满。

3 个答案:

答案 0 :(得分:0)

我认为你必须使用for循环而不是foreach,因为for循环创建带索引的复选框控件名称。

@for (int i = 0; i < Model.RoleRights.Count; i++)
{
     @Html.CheckBoxFor(x => Model.RoleRights[i].CHECKED)
} 

答案 1 :(得分:0)

我用editortemplates修复了它。这个例子帮助了我。 http://www.itorian.com/2013/04/nested-collection-models-in-mvc-to-add.html

答案 2 :(得分:0)

您编写CHECKED输入的方式不正确。这样,表单将一个请求参数发送到刚刚命名的服务器: CHECKED 要使它正确绑定到RoleEditViewModel,它必须是:RoleRights[index].CHECKED其中index是一个以0开头的数字序列。 所以,如果你要发送3个rolerights,那么rquest参数在哪里:

RoleRights[0].CHECKED
RoleRights[1].CHECKED
RoleRights[2].CHECKED

在razor中你的foreach循环看起来像这样:

@{int index = 0;}
@foreach (var item in Model.RoleRights)
{
    @Html.CheckBox(string.format("RoleRights[{0}].CHECKED", ++index), item.CHECKED)
}

请参阅Phil Haacks关于此列表的模型绑定的文章以及一些更复杂的示例http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/