【问题标题】:DropDownListFor not respecting Selected property of SelectListDropDownListFor 不尊重 SelectList 的 Selected 属性
【发布时间】:2013-07-17 23:23:51
【问题描述】:

我有以下代码行:

@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。想法?

【问题讨论】:

  • 你能把你面临的问题说得更清楚吗??
  • 当您的意思是 GET 时,选项值会在您回发后重置?
  • @RameezAhmedSayad,当页面加载(IE GET)时,默认值不会呈现为“selected='selected'”,但在 POST 上,它是。在 GET 期间设置了一个非零默认值 (2)。
  • Model.TimeOption的类型是什么?
  • 以下是对“mvc dropdownlistfor not selection selected value”进行网络搜索的前五个结果:12345。你有什么尝试吗? :-)

标签: c# asp.net-mvc


【解决方案1】:

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

当你这样做时:

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

...HTML 助手将尽其所能使用您在SelectList 中设置为Selected = true 的值。它将:

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

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

因此,在您的情况下,它将使用您模型上的 TimeOption 的当前值作为选定值。这应该没问题,因为这就是你在SelectList 中要求的内容((int)Model.TimeOption),对吧?

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

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

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

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

【讨论】:

  • 似乎是疏忽或奇怪的设计决定。我将整数枚举值分配给 ViewData,它可以工作。感谢您的帮助。
  • 谢谢,这为我节省了很多时间。他们绝对应该让这个工作,这是相当贫民区不得不做的... ViewBag.RentFrequency = Enums.RentFrequency.Monthly.ToDictionary().Select(x => new SelectListItem { Text = x.Value, Value = x.Key .ToString(), Selected = (x.Key == (int)tenant.RentFrequency) }).ToList(); ViewBag.RentFrequency = (int)tenant.RentFrequency;
  • 在我的例子中,用于所选值的模型属性是“Title”(如称呼)。在 ViewData 中为页面标题设置了相同的属性。很烦人。
  • 有任何解释为什么 DropDown 被设计成这样吗?
【解决方案2】:

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

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

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

NB - 我不确定 Model.TimeOptions 是什么类型 - 如果它不是 IEnumerable 则替换它。 (如果它已经是一个列表,则不需要 .ToList())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2021-11-12
    相关资源
    最近更新 更多