3

我的模型:

 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">
            &nbsp;
          </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 始终为空。我在这里错过了一些简单的事情吗?

4

2 回答 2

6

两个问题:

您的第一个问题是您在构造函数中重置列表,因此当表单发布并且模型绑定器实例化模型的实例时,您正在重新设置列表。将其更改为合并以仅在列表为时重新分配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>
}
于 2013-04-23T10:51:47.210 回答
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>
于 2013-04-23T10:50:07.900 回答