我的模特:
public class SendFileDeviceViewModel
{
public SendFileDeviceViewModel()
{
PolicyList = new List<SendFileDevicePoliciesViewModel>();
}
public string DeviceName { get; set; }
public int DeviceId { get; set; }
public string ManagementGroupName { get; set; }
public int ManagementGroupId { get; set; }
public bool ReloadConfiguration { get; set; }
public bool ImmediateSend { get; set; }
public DateTime TimeToSend { get; set; }
public List<SendFileDevicePoliciesViewModel> PolicyList { get; set; }
}
public class SendFileDevicePoliciesViewModel
{
public int PackageTemplateId { get; set; }
public string PolicyName { get; set; }
public string PolicyType { get; set; }
public string DefinedAt { get; set; }
public bool ResendPolicy { get; set; }
}
我的观点:
<h2>Send files to a Device @Model.DeviceName</h2>
<h3>Reload configuration settings</h3>
@Html.CheckBoxFor(m => m.ReloadConfiguration) @Html.LabelFor(m => m.ReloadConfiguration)
<h3>Select the policies to reload</h3>
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.DeviceId)
@Html.HiddenFor(m => m.ManagementGroupId)
@Html.ValidationSummary(true)
if (Model.PolicyList.Count() > 0)
{
<table>
<caption>
Policies available for this device</caption>
<thead>
<tr>
<th scope="col">
</th>
<th scope="col">
Policy Name
</th>
<th scope="col">
Policy Type
</th>
<th scope="col">
Defined At
</th>
</tr>
</thead>
<tbody>
@foreach (var policies in Model.PolicyList)
{
<tr>
@*<td>@Html.CheckBox("PackageTemplateId", new { value = policies.PackageTemplateId })</td>*@
<td>@Html.CheckBoxFor(m => policies.ResendPolicy)</td>
<td>@policies.PolicyName</td>
<td>@policies.PolicyType</td>
<td>@policies.DefinedAt</td>
</tr>
}
</tbody>
</table>
}
<div class="editor-label">
@Html.LabelFor(m => m.ImmediateSend)
</div>
<div class="editor-field">
@Html.CheckBoxFor(m => m.ImmediateSend)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.TimeToSend)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.TimeToSend)
</div>
<p>
<input type="submit" value="Send files" /></p>
我的问题是从控制器检索模型时,PolicyList始终为空。我在这里错过了一些简单的东西吗?
答案 0 :(得分:5)
两个问题:
您的第一个问题是您正在构造函数中重置列表,因此当发布表单并且模型绑定器实例化模型的实例时,您将重新设置列表。如果列表为null
,则将其更改为合并以仅重新分配:
public SendFileDeviceViewModel()
{
PolicyList = PolicyList ?? new List<SendFileDevicePoliciesViewModel>();
}
您的下一个问题是foreach
。为了正确索引name
属性(因此模型绑定器可以执行此操作),您需要使用for
循环。另外,请将Id保存在HiddenFor
。
尝试使用此代替foreach
:
@for (int i = 0; i < Model.PolicyList.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(m => m.PolicyList[i].PackageTemplateId)
@Html.CheckBoxFor(m => m.PolicyList[i].ResendPolicy)
</td>
<td>@Model.PolicyList[i].PolicyName</td>
<td>@Model.PolicyList[i].PolicyType</td>
<td>@Model.PolicyList[i].DefinedAt</td>
</tr>
}
答案 1 :(得分:3)
原因是您不尊重输入字段的naming convention
。您应该使用foreach
循环或自定义编辑器模板替换视图中的for
循环:
<tbody>
@for (var i = 0; i < Model.PolicyList.Count; i++)
{
<tr>
<td>@Html.CheckBoxFor(x => x.PolicyList[i].ResendPolicy)</td>
<td>@Html.DisplayFor(x => x.PolicyList[i].PolicyName)</td>
<td>@Html.DisplayFor(x => x.PolicyList[i].PolicyType)</td>
<td>@Html.DisplayFor(x => x.PolicyList[i].DefinedAt)</td>
</tr>
}
</tbody>
此外,现在只会绑定ResendPolicy
属性,因为这是唯一具有相应输入字段的属性(在您的情况下为复选框)。如果你想绑定其他的,你可能需要包含相应的隐藏字段:
<tbody>
@for (var i = 0; i < Model.PolicyList.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(x => x.PolicyList[i].PackageTemplateId)
@Html.CheckBoxFor(x => x.PolicyList[i].ResendPolicy)
</td>
<td>
@Html.HiddenFor(x => x.PolicyList[i].PolicyName)
@Html.DisplayFor(x => x.PolicyList[i].PolicyName)
</td>
<td>
@Html.HiddenFor(x => x.PolicyList[i].PolicyType)
@Html.DisplayFor(x => x.PolicyList[i].PolicyType)
</td>
<td>
@Html.HiddenFor(x => x.PolicyList[i].DefinedAt)
@Html.DisplayFor(x => x.PolicyList[i].DefinedAt)
</td>
</tr>
}
</tbody>