首次加载View时,DropDownListFor和ListBoxFor都会显示多个选定的项目.
单击“提交”按钮时,所选项目集合将回发到Controller操作,并且视图将刷新,ListBoxFor仍显示两个选定项目,但DropDownListFor仅显示一个选定项目.
控制器动作正在构建MultiSelectList,如下所示:
vm.TasksFilterGroup.Assignees = new MultiSelectList(employees,"Id","FullName",new string[] { "51b6f06a-e04d-4f98-88ef-cd0cfa8a2757","51b6f06a-e04d-4f98-88ef-cd0cfa8a2769" });
View代码如下所示:
<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,multiple = "multiple" }) </div>
为什么DropDownListFor会在提交后丢失多个选择,但ListBoxFor却没有?
解决方法
添加multiple =“multiple”属性会更改显示,但不会更改这些方法执行的代码的功能.
如果你检查source code,你会注意到DropDownListFor()的所有重载最终都会调用私有静态MvcHtmlString DropDownListHelper()方法,类似的ListBoxFor()最终会调用私有静态MvcHtmlString ListBoxHelper()方法.
这两个方法都调用私有静态MvcHtmlString SelectInternal()方法,但区别在于DropBownListHelper()传递allowMultiple = false,而ListBoxHelper()传递allowMultiple = true.
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName,typeof(string[])) : htmlHelper.GetModelStateValue(fullName,typeof(string));
然后在为< option>构建html时使用defaultValue的值.元素,用于设置所选属性.
对于ListBoxFor(),defaultValue的值将是SelectedAssignees属性定义的数组.在DropDownListFor()的情况下,它返回null,因为您的属性的值不能转换为字符串(它的数组).
因为defaultValue为null,所以< option>都不是元素具有选定的属性集,并且您将丢失模型绑定.
作为旁注,如果您在将模型传递给视图之前在GET方法中设置SelectedAssignees的值,您将看到在使用DropDownListFor()时没有选择它们,原因与上述相同.
vm.TasksFilterGroup.Assignees = new SelectList(employees,"FullName" });
使用DropDownListFor()或ListBoxFor()方法时,没有必要设置第3个参数,因为它绑定到(SelectedAssignees)的属性的值决定了哪些选项被选中(第3个参数被方法忽略).如果要选择与这些Guid值匹配的选项,则在GET方法中使用
vm.TasksFilterGroup.SelectedAssignees= new string[]{ "51b6f06a-e04d-4f98-88ef-cd0cfa8a2757","51b6f06a-e04d-4f98-88ef-cd0cfa8a2769" };