10

我有以下代码行:

@Html.DropDownListFor(x => x.TimeOption, new SelectList(Model.TimeOptions, "Value", "Name", (int)Model.TimeOption))

下拉列表已正确构建,并且 Selected 确实是正确的,但 MVC 不会在选择了正确项目的情况下绘制下拉列表。标记不会输出选项上的选定属性。

输出呈现为:

<option value="0">Past Day</option>
<option value="1">Past Week</option>
<option value="2">Past Month</option>
<option value="3">Past Year</option>
<option value="4">Start of Time</option>

但是,如果您查看随附的屏幕截图,您会发现它已正确选择:

观察名单

这仅影响 GET,不影响 POST。想法?

4

2 回答 2

22

这往往会让人们很困惑——显然 MVC 5 的路线图包括更直观的 DropDownList 助手。

当你这样做时:

@Html.DropDownListFor(x => x.TimeOption ...)

... HTML 助手将尽其所能使用您Selected = trueSelectList. 它会:

  • 尝试从中获取它ModelState- 它不会在 GET 请求中获取
  • 尝试从中获取它ViewData- 它得到它,因为您TimeOption的模型上有一个属性。

只有当这两种尝试都失败时,它才会屈服,并使用你要求它使用的东西。

因此,在您的情况下,它将使用TimeOption您模型上的当前值作为选定值。哪个应该没问题,因为那是您SelectList无论如何要求的((int)Model.TimeOption),对吗?

错误的。因为它不会像您一样将您的财产(enum?)投给int您。它会将其转换为字符串。对于enum产生枚举名称的 an - 例如PastMonth. 如果TimeOption是您的自定义类,它将是ToString().

然后,当它没有找到该字符串作为您的<select>值之一(因为它们都是整数)时,它决定不选择任何内容。

简而言之:SelectListItem.Selected对助手没有影响。如果您的助手调用指定了一个名称(字面意思或通过 lambda 表达式),助手将使用该名称中的任何内容ModelStateViewData与该名称一起使用的任何内容,并将其转换为字符串。

在大多数情况下,这发生在枚举中。绕过它的最简单方法是使用枚举的名称,而不是它的 int 表示,作为SelectListItem.

于 2013-07-17T09:06:57.820 回答
2

您已经在上面得到了很好的解释,说明它为什么不起作用,只是为了添加我的 2p

一般来说,我更喜欢使用可枚举的 SelectListItems 作为下拉项的来源,尽管两者都应该有效。这样做更可取,因为不需要指定选择了哪个项目 - MVC 助手将从 Value 与 TimeOption.ToString() 方法匹配的那个人推断它。

IE

@Html.DropDownListFor(x => x.TimeOption, ((IEnumerable<TimeOption>)Model.TimeOptions).ToList().ConvertAll(y => new SelectListItem(){Text = y.Name, Value = y.Value.ToString()})

注意 - 我不确定 Model.TimeOptions 是什么类型 - 如果它不是 IEnumerable< TimeOption> 然后替换它。(如果它已经是一个列表,那么 .ToList() 不是必需的)

于 2013-07-17T15:23:51.067 回答