问题描述
如果这个道歉已经问;有一百万的方式句话就那么寻找答案已被证明很难。
我有一个视图模型具有以下属性:
公共类AssignSoftwareLicenseViewModel
{
公众诠释LicenseId {搞定;组; }
公众的ICollection< SelectableDeviceViewModel>设备{搞定;组; }
}
SelectableDeviceViewModel的简化版本是这样的:
公共类SelectableDeviceViewModel
{
公众诠释DeviceInstanceId {搞定;组; }
公共BOOL IsSelected {搞定;组; }
公共字符串名称{;组; }
}
在我看来,我试图以显示设备的属性可编辑复选框列表,输入表单中。
目前,我的看法是这样的:
@using(Html.BeginForm())
{
@ Html.HiddenFor(X => Model.LicenseId)
<表>
&所述; TR>
<第i个姓名和LT; /第i
百分位>< /第i
< / TR>
@foreach(在Model.Devices SelectableDeviceViewModel设备)
{
@ Html.HiddenFor(X => device.DeviceInstanceId)
&所述; TR>
< TD> @ Html.CheckBoxFor(X => device.IsSelected)LT; / TD>
< TD> @ device.Name< / TD>
< / TR>
}
< /表> <输入类型=提交值=分配/>
}
问题是,当模型被调回控制器,设备为null。
我的假设是,这种情况正在发生,因为即使我编辑的内容,该设备的属性从未明确地包含在表单中。我试着包括它HiddenFor,但只是导致有一个空列表而不是空的模式。
任何想法,我在做什么错在这里?
No, your assumption is wrong. The reason this doesn't get bound properly is because your input fields doesn't have correct names. For example they are called name="IsSelected"
instead of name="Devices[0].IsSelected"
. Take a look at the correct wire format that needs to be used to bind to collections: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
It happens because of the foreach
loop that you used in your view. You used x => device.IsSelected
as lambda expression for the checkbox but this doesn't take into account the Devices property at all (as you can see by looking at the generated source code of your web page).
Personally I would recommend you using editor templates as they respect the navigational context of complex properties and generate correct input names. So get rid of the entire foreach
loop in your view and replace it with a single line of code:
@Html.EditorFor(x => x.Devices)
and now define a custom editor template that will automatically be rendered by ASP.NET MVC for each element of the Devices collection. Warning: the location and name of this template are very important as this works by convention: ~/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>
Another approach (which I don't recommend) is to change your current ICollection
in your view model to an indexed collection (such as an IList<T>
or an array T[]
):
public class AssignSoftwareLicenseViewModel
{
public int LicenseId { get; set; }
public IList<SelectableDeviceViewModel> Devices { get; set; }
}
and then instead of the foreach use a for
loop:
@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>
}
这篇关于MVC3 - 视图模型复杂类型列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!