.NET Core 2.1下拉框自动添加multiple属性问题求助
首先得搞清楚为什么会出现这个情况:ASP.NET Core的TagHelper会根据asp-for绑定的属性类型自动判断下拉框是否为多选。你绑定的AccountNumbers是IEnumerable<SelectListItem>类型,TagHelper会默认认为这是需要支持多选的场景,所以自动给<select>加上了multiple="multiple"属性。
下面给你两种实用的解决思路:
思路一:手动控制select标签,不绑定选项集合到asp-for
既然AccountNumbers只是用来提供下拉选项的,那我们可以不用把它绑定到asp-for,而是手动指定表单提交时的参数名,同时保留asp-items来渲染选项:
<form asp-action="FilterOrders" asp-controller="Order" id="ordersFilterForm" method="post"> <div class="form-group"> <label class="control-label">Account Numbers:</label> <!-- 去掉asp-for,手动设置name属性 --> <select name="SelectedAccountNumber" class="form-control" asp-items="@Model.AccountNumbers"> </select> </div> <div class="form-group"> <input type="submit" value="Submit" class="btn btn-default" /> </div> </form>
然后在控制器的FilterOrders方法里,直接通过参数接收选中的值:
[HttpPost] public IActionResult FilterOrders(string selectedAccountNumber) { // 在这里处理你的过滤逻辑 return PartialView("_FilterOrders", vm); }
这种方法不需要修改视图模型,完全靠手动指定表单参数名来实现,也不会生成多选属性。
思路二:规范视图模型的职责划分(更推荐)
其实你之前添加的属性并不多余——AccountNumbers是用来展示选项的集合,而选中的值需要一个单独的属性来绑定,这才是MVC模型绑定的标准做法。我们可以把属性名改成更贴合场景的SelectedAccountNumber:
修改后的视图模型:
public class OrdersFilterViewModel { [Display(Name = "Account Numbers:")] public IEnumerable<SelectListItem> AccountNumbers { get; set; } // 用来绑定选中的账户号,和你的AccountNumber类型保持一致(这里假设是字符串) public string SelectedAccountNumber { get; set; } }
初始化视图模型的时候,保留原来的SelectList初始化,还可以顺便设置默认选中值:
var vm = new OrdersFilterViewModel { AccountNumbers = new SelectList(_context.Account.Where(m => m.UserID == userId), "AccountNumber", "AccountNumber", account), SelectedAccountNumber = account }; return PartialView("_FilterOrders", vm);
视图里的select标签改成绑定这个新属性:
<select asp-for="SelectedAccountNumber" class="form-control" asp-items="@Model.AccountNumbers"> </select>
这种方式的好处是,回发的时候模型绑定会自动把选中的值填充到SelectedAccountNumber属性里,不需要手动处理表单请求,代码更整洁,也符合MVC的设计思想。
关于设置multiple="false"的说明
你提到能不能直接设置multiple="false"来恢复正常下拉框,实际测试下来,TagHelper会因为asp-for绑定的是IEnumerable类型而强制覆盖这个属性,最终还是会生成multiple="multiple",所以这个方法是行不通的,不建议尝试。
内容的提问来源于stack exchange,提问作者Sum None

