asp.net-mvc - 为什么 DropDownListFor 在提交后会丢失多选,而 ListBoxFor 不会?

标签 asp.net-mvc asp.net-mvc-5.2

我已经阅读了很多有关使用 MultiSelectList 的文章,但尚未了解我的 DropDownListFor 出了什么问题。我有一个 ListBoxFor ,具有相同的 View、ViewModel 和数据,运行良好。我想使用 DropDownListFor 因为它的 optionLabel 参数是 ListBoxFor 没有的。

首次加载 View 时,DropDownListFor 和 ListBoxFor 都会显示多个选定的项目。

Initial View

单击“提交”按钮后,选定的项目集合将正常发送回 Controller 操作,并且刷新 View ,ListBoxFor 仍显示两个选定的项目,但 DropDownListFor 仅显示一个选定的项目。

Refreshed View 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 = falseListBoxHelper()通过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 (它是一个数组)。

因为defaultValuenull<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/

相关文章:

c# - 在 ASP.NET MVC 中使用嵌套子模型和 PartialView 进行模型绑定(bind)

c# - MVC路由静态文件

asp.net-mvc - Serilog 仅在非异步操作时写入接收器,即使如此,也仅在首次运行时写入接收器

asp.net - BC30561 : 'Html' is ambiguous, 从命名空间或类型 'System.Web.WebPages, System.Web.Mvc' 导入

asp.net-mvc - ViewData 和 ViewBag 在哪里?

c# - 不能动态调度扩展方法

asp.net-mvc - 在 MVC 中,什么时候使用 <%= %> 和 <% %>?

ravendb - 嵌入 MVC 时如何以编程方式初始化 Race nFS FileStore

c# - 没有为重载的模拟方法引发回调

asp.net-mvc - 使用 asp.net mvc 使某个枚举值的验证失败