在MVC中如何将选中的Checkbox项传递到Controller?
解决方案
问题根因
你当前写法的问题在于:给SomeType1的复选框用索引绑定了Value字段,ASP.NET Core模型绑定遇到索引格式的参数名时,会自动为每个索引位置创建对应实体对象,未勾选的复选框不会提交值,所以你会拿到和可选列表长度一致的集合,未勾选项的字段为默认空值,因此看起来返回了完整列表。
方案1:新增选中状态绑定(适合需要前端传递完整模型字段的场景)
步骤1:修改SomeType1模型新增选中标识
public class SomeType1 { public string Id { get; set; } public string Name { get; set; } public string Value { get; set; } public string ExtraInfo { get; set; } // 新增复选框绑定字段 public bool IsChecked { get; set; } }
步骤2:调整视图绑定逻辑
把需要保留的模型字段用隐藏域提交,复选框绑定IsChecked属性:
@model MainViewModel @{ ViewData["Title"] = "Home Page"; } @using (Html.BeginForm("Index", "Home")) { <div class="text-center"> <input type="text" name="search" /> <input type="submit" value="Submit" /> </div> <br /> for (int i = 0; i < Model.SomeModel.SomeType1.Count; i++) { <b>Some Type 1</b> <div class="checkbox"> <label> <!-- 隐藏域提交需要保留的其他字段 --> <input type="hidden" name="SomeType1[@i].Id" value="@Model.SomeModel.SomeType1[i].Id" /> <input type="hidden" name="SomeType1[@i].Name" value="@Model.SomeModel.SomeType1[i].Name" /> <input type="hidden" name="SomeType1[@i].Value" value="@Model.SomeModel.SomeType1[i].Value" /> <input type="hidden" name="SomeType1[@i].ExtraInfo" value="@Model.SomeModel.SomeType1[i].ExtraInfo" /> <!-- 复选框绑定选中状态 --> <input type="checkbox" name="SomeType1[@i].IsChecked" value="true" /> @Model.SomeModel.SomeType1[i].Name <input type="hidden" name="SomeType1[@i].IsChecked" value="false" /> </label> </div> } for (int i = 0; i < Model.SomeModel.SomeOtherType2.Count; i++) { <b>SomeOtherType2</b> <div class="checkbox"> <label> <input type="checkbox" name="SomeOtherType2" value="@Model.SomeModel.SomeOtherType2[i].Value" /> @Model.SomeModel.SomeOtherType2[i].Name </label> </div> } }
步骤3:Post Action中过滤选中项
[HttpPost] public IActionResult Index(string search, List<SomeType1> SomeType1, string[] SomeOtherType2) { // 过滤拿到勾选的SomeType1项 var checkedSomeType1 = SomeType1.Where(x => x.IsChecked).ToList(); // 如果SomeOtherType2需要拿到完整模型,可通过选中的Value匹配原始数据(原始数据可从数据库/缓存/静态存储获取) var allSomeOtherType2 = GetAllSomeOtherType2(); // 替换为你获取原始列表的逻辑 var checkedSomeOtherType2 = allSomeOtherType2.Where(x => SomeOtherType2.Contains(x.Value)).ToList(); return View(); }
方案2:提交选中标识后台匹配(更安全,避免前端篡改数据)
如果你不需要前端传递额外字段,也可以直接提交选中项的唯一标识(比如Id/Value),后台从数据源匹配完整模型,不需要修改实体:
视图调整
for (int i = 0; i < Model.SomeModel.SomeType1.Count; i++) { <b>Some Type 1</b> <div class="checkbox"> <label> <input type="checkbox" name="CheckedSomeType1Values" value="@Model.SomeModel.SomeType1[i].Value" /> @Model.SomeModel.SomeType1[i].Name </label> </div> }
Action调整
[HttpPost] public IActionResult Index(string search, string[] CheckedSomeType1Values, string[] SomeOtherType2) { var allSomeType1 = GetAllSomeType1(); // 替换为你获取原始SomeType1列表的逻辑 var checkedSomeType1 = allSomeType1.Where(x => CheckedSomeType1Values.Contains(x.Value)).ToList(); return View(); }
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

