发送检查 html table 视图无效时返回给客户端

Sent checked html table view back to client when invalid

当我的 Model.State 无效时,我想 return 带有选中复选框的视图。

你会如何更改我的代码?我的方法有可能吗?

VIEW

       @model ListTest.Models.PeopleListViewModel


    @{
        var hasMoreThanOnePerson = @Model.People.Count > 1;   
    }

    @Html.BeginForm("Save", "Home")
    {

    @Html.ValidationSummary(false)

    <table>
        @foreach (var item in Model.People)
        {
            <tr>
                @if (hasMoreThanOnePerson)
             {
               <td>
               <input type="checkbox" name="SelectedIds" value="@item.PersonId" />
                </td>
              }
              else
              {
                 @Html.Hidden("SelectedIds", item.PersonId)
              }

                <td>
                    <input type="text" value="@item.Name" />
                </td>
            </tr>
        }
    </table>
    <input type="submit" value="Save" />
    }

VIEWMODEL

public class PeopleListViewModel
    {
        public PeopleListViewModel()
        {
            SelectedIds = new int[] { };
        }

        [MinLength(1, ErrorMessage = "Minimum one person must be selected!")]
        public int[] SelectedIds { get; set; }

        public List<Person> People { get; set; }
    }

控制器

public ActionResult Index()
{ 
    var people = new List<Person> {
        new Person { Name = "Horst", PersonId = 10 }, 
        new Person { Name = "Michael", PersonId = 20} 
    };

    return View(new PeopleListViewModel { People = people });
}

[HttpPost]
public ActionResult Save(PeopleListViewModel viewModel)
{

    if (ModelState.IsValid)
    { 

    }

    viewModel.People = new List<Person> { new Person { Name = "Horst", PersonId = 10 }, new Person { Name = "bernarnd", PersonId = 20 } };

    return View("Index", viewModel);
}

几乎没有什么要改变的

首先,更改您的 People 模型以包含 IsSelected 属性,我们想取消您的 SelectedIds 方法

其次,为了 post 来自客户端的数据,我们需要将您的 foreach 重写为 for 以便正确索引字段,我们还将为您要保留的属性添加一些额外的 HiddenFor(因为验证失败时我们不再重新填充您的模型),您的 table 将是:

<table>
    @for (int i = 0; i < Model.People.Count; i++)
    {
        <tr>
            @Html.HiddenFor(m => m.People[i].PersonID)
            @Html.HiddenFor(m => m.People[i].Name)
            @if (hasMoreThanOnePerson)
            {
               <td>
                   @Html.CheckBoxFor(m => m.People[i].IsSelected)
               </td>
           }
           else
           {
               @Html.HiddenFor(m => m.People[i].IsSelected)
           }

           <td>
              <input type="text" value="@Model.People[i].Name" />
           </td>
        </tr>
    }
</table>

最后,如果验证失败,我们不会在您的操作方法中重新分配您的 People 列表,只是 return 传入的模型。如果您想获得选定的人,请使用我在下面添加的代码。此外,因为我们不再有 SelectedIds,所以我们可以执行自己的验证:

[HttpPost]
public ActionResult Save(PeopleListViewModel viewModel)
{
    List<People> selected = viewModel.People
        .Where(p => p.IsSelected)
        .ToList();

    if (selected.Any())
    { 
       //it's valid
      List<int> selectedIds = selected
          .Select(s => s.PersonID)
          .ToList();
    }

    return View("Index", viewModel);
}