Ответ 1
Мое предположение заключается в том, что это происходит, потому что, хотя я редактируя его содержимое, свойство Devices никогда явно не указано включены в форму.
Нет, ваше предположение неверно. Причина, по которой это не связано должным образом, заключается в том, что ваши поля ввода не имеют правильных имен. Например, они называются name="IsSelected"
вместо name="Devices[0].IsSelected"
. Взгляните на правильный формат проводов, который необходимо использовать для привязки к коллекциям: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Но почему это происходит?
Это происходит из-за цикла foreach
, который вы использовали в своем представлении. Вы использовали x => device.IsSelected
в качестве лямбда-выражения для этого флажка, но это вообще не учитывает свойство Devices (как вы можете видеть, глядя на сгенерированный исходный код вашей веб-страницы).
Так что мне делать?
Лично я бы рекомендовал вам использовать шаблоны редактора, поскольку они уважают навигационный контекст сложных свойств и генерируют правильные имена ввода. Поэтому избавьтесь от всего цикла foreach
в вашем представлении и замените его на одну строку кода:
@Html.EditorFor(x => x.Devices)
и теперь определите настраиваемый шаблон редактора, который будет автоматически отображаться ASP.NET MVC для каждого элемента коллекции Devices. Предупреждение: расположение и имя этого шаблона очень важны, поскольку это работает по соглашению: ~/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>
}