我已经阅读了很多有关使用 MultiSelectList 的文章,但尚未了解我的 DropDownListFor 出了什么问题。我有一个 ListBoxFor ,具有相同的 View、ViewModel 和数据,运行良好。我想使用 DropDownListFor 因为它的 optionLabel 参数是 ListBoxFor 没有的。
首次加载 View 时,DropDownListFor 和 ListBoxFor 都会显示多个选定的项目。
单击“提交”按钮后,选定的项目集合将正常发送回 Controller 操作,并且刷新 View ,ListBoxFor 仍显示两个选定的项目,但 DropDownListFor 仅显示一个选定的项目。
Controller 操作正在构造 MultiSelectList,如下所示:
vm.TasksFilterGroup.Assignees = new MultiSelectList(employees, "Id", "FullName", new string[] { "51b6f06a-e04d-4f98-88ef-cd0cfa8a2757", "51b6f06a-e04d-4f98-88ef-cd0cfa8a2769" });
查看代码如下所示:
<div class="form-group">
<label>ListBoxFor</label>
@Html.ListBoxFor(m => m.TasksFilterGroup.SelectedAssignees, Model.TasksFilterGroup.Assignees, new { @class = "form-control", multiple = "multiple" })
</div>
<div class="form-group">
<label>DropDownListFor</label>
@Html.DropDownListFor(m => m.TasksFilterGroup.SelectedAssignees, Model.TasksFilterGroup.Assignees, new { @class = "form-control", multiple = "multiple" })
</div>
为什么提交后 DropDownListFor 会丢失多选,而 ListBoxFor 不会?
最佳答案
正如方法名称所暗示的那样,DropDownListFor()
用于创建<select>
(选择 1 个选项)和 ListBoxFor()
用于创建<select multiple>
(选择多个选项)。虽然这两种方法共享许多通用代码,但它们确实会产生不同的结果。
添加multiple="multiple"
属性会更改显示,但不会更改这些方法执行的代码的功能。
如果您检查 source code ,您会注意到 DropDownListFor()
的所有重载最终调用private static MvcHtmlString DropDownListHelper()
方法,类似ListBoxFor()
最终调用private static MvcHtmlString ListBoxHelper()
方法。
这两个方法都调用 private static MvcHtmlString SelectInternal()
方法,但不同的是DropDownListHelper()
通过allowMultiple = false
而ListBoxHelper()
通过allowMultiple = true
.
在SelectInternal()
内方法,关键代码行是
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
defaultValue
的值然后在为 <option>
构建 html 时使用元素并用于设置 selected
属性。
以ListBoxFor()
为例,defaultValue
的值将是由 SelectedAssignees
定义的数组属性(property)。以DropDownListFor()
为例它返回null
因为你的属性(property)的值(value)不能转换为 string
(它是一个数组)。
因为defaultValue
是 null
,<option>
都没有元素有 selected
属性集,并且您失去模型绑定(bind)。
作为旁注,如果您要设置 SelectedAssignees
的值在将模型传递给 View 之前的 GET 方法中,您将看到使用 DropDownListFor()
时没有选择任何一个。出于与上述相同的原因。
另请注意,生成 SelectList
的代码应该只是
vm.TasksFilterGroup.Assignees = new SelectList(employees, "Id", "FullName" });
使用DropDownListFor()
时设置第三个参数是没有意义的。或ListBoxFor()
方法,因为它的绑定(bind)属性值 ( SelectedAssignees
) 决定了选择哪些选项(第三个参数被方法忽略)。如果您想要与 Guid
匹配的选项要选择的值,然后在 GET 方法中使用
vm.TasksFilterGroup.SelectedAssignees= new string[]{ "51b6f06a-e04d-4f98-88ef-cd0cfa8a2757", "51b6f06a-e04d-4f98-88ef-cd0cfa8a2769" };
关于asp.net-mvc - 为什么 DropDownListFor 在提交后会丢失多选,而 ListBoxFor 不会?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40725358/