MVC3 - 视图模型与复杂类型的列表(MVC3 - Viewmodel with list of

2019-06-26 13:21发布

如果这个道歉已经问; 有一百万的方式句话就那么寻找答案已被证明很难。

我有以下属性的视图模型:

public class AssignSoftwareLicenseViewModel
{
    public int LicenseId { get; set; }
    public ICollection<SelectableDeviceViewModel> Devices { get; set; }
}

SelectableDeviceViewModel的简化版本是这样的:

public class SelectableDeviceViewModel
{
    public int DeviceInstanceId { get; set; }
    public bool IsSelected { get; set; }
    public string Name { get; set; }
}

在我看来,我试图显示可编辑复选框的列表中设备的属性,输入表单中。 目前,我的看法是这样的:

@using (Html.BeginForm())
{
    @Html.HiddenFor(x => Model.LicenseId)
    <table>
        <tr>
            <th>Name</th>
            <th></th>
        </tr>
        @foreach (SelectableDeviceViewModel device in Model.Devices)
        {
            @Html.HiddenFor(x => device.DeviceInstanceId)
            <tr>
                <td>@Html.CheckBoxFor(x => device.IsSelected)</td>
                <td>@device.Name</td>
            </tr>
        }
    </table>

    <input type="submit" value="Assign" />
}

问题是,当模型被调回控制器,设备为空。

我的假设是,这种情况正在发生,因为即使我编辑的内容,该设备的属性从未明确地包含在表单中。 我想包括它HiddenFor,但只是导致有一个空列表而不是空的模型。

任何想法,我做错了什么?

Answer 1:

我的假设是,这种情况正在发生,因为即使我编辑的内容,该设备的属性从未明确地包含在表单中。

不,你的假设是错误的。 这没有得到正确绑定的原因是因为你的输入字段没有正确的名称。 例如,它们被称为name="IsSelected" ,而不是name="Devices[0].IsSelected" 。 看看正确的线格式,需要使用绑定到集合: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

但是,为什么出现这种情况?

这是因为在中foreach您在视图中使用循环。 你用x => device.IsSelected作为复选框lambda表达式,但这并不考虑设备的属性在所有(你可以通过查看网页的源代码生成见)。

所以我该怎么做?

个人而言,我会建议你使用编辑模板,因为他们尊重复杂性的导航上下文和产生正确的输入名称。 因此,摆脱了整个的foreach在你看来循环,并用一行代码替换它:

@Html.EditorFor(x => x.Devices)

现在定义将自动ASP.NET MVC的设备集合中的每个元素呈现的自定义编辑模板。 警告:此模板的位置和名称都为这个工程按照惯例很重要的: ~/Views/Shared/EditorTemplates/SelectableDeviceViewModel.cshtml

@model SelectableDeviceViewModel
@Html.HiddenFor(x => x.DeviceInstanceId)
<tr>
    <td>@Html.CheckBoxFor(x => x.IsSelected)</td>
    <td>@Html.DisplayFor(x => x.Name)</td>
</tr>

另一种方法(其不推荐)是更改当前ICollection在视图模型索引的集合(例如一个IList<T>或阵列T[]

public class AssignSoftwareLicenseViewModel
{
    public int LicenseId { get; set; }
    public IList<SelectableDeviceViewModel> Devices { get; set; }
}

然后,而不是在foreach使用for循环:

@for (var i = 0; i < Model.Devices.Count; i++)
{
    @Html.HiddenFor(x => x.Devices[i].DeviceInstanceId)
    <tr>
        <td>@Html.CheckBoxFor(x => x.Devices[i].IsSelected)</td>
        <td>@Html.DisplayFor(x => x.Devices[i].Name</td>
    </tr>
}


Answer 2:

EditorFor模板工作,并保持代码的清洁。 你不需要循环和模型被调回正常。

但是,有没有人有复杂的ViewModels(嵌套EditorFor模板)验证问题? 我使用的剑道验证,并正在到各种各样的jQuery的错误。



文章来源: MVC3 - Viewmodel with list of complex types