DropDownList设置在asp.net MVC中select的项目
我注意到在我看来,在asp.net MVC中的错误,或者只是我做错了什么。 我目前正在使用1.0,所以也许这是2.0版本中将要解决的问题。 但无论如何,我们走吧。
当我的视图模型有一个属性是一个下拉列表中声明的ID相同的名称,选定的项目将被忽略,呈现的HTML没有任何select。 不知道我做错了什么,但更改id的名称可以解决问题。 我简化了这个例子,希望是明确的,否则请让我知道。
这里是我的视图,其中声明的ID与模型中的列表名称相同:
<table border="0" cellpadding="0" cellspacing="0"> <tr> <td> <%= Html.DropDownList("IsMultipleServicers", Model.IsMultipleServicers) %> </td> </tr> </table>
和呈现的Html
<table border="0" cellpadding="0" cellspacing="0"> <tr> <td> <select id="IsMultipleServicers" name="IsMultipleServicers"> <option value="false">No</option> <option value="true">Yes</option> </select> </td> </tr> </table>
现在让我们做一个小小的改变。 我会改变声明的ID是不同的东西。
这是我的观点:
<table border="0" cellpadding="0" cellspacing="0"> <tr> <td> <%= Html.DropDownList("MultipleServicers", Model.IsMultipleServicers) %> </td> </tr> </table>
现在,呈现的HTML:
<table border="0" cellpadding="0" cellspacing="0"> <tr> <td> <select id="IsMultipleServicers" name="IsMultipleServicers"> <option value="false">No</option> <option selected="selected" value="true">Yes</option> </select> </td> </tr> </table>
请注意,现在我得到一个选定的选项,这将是列表中的第二个元素。
这里是我的ViewModel只是为了把所有东西都捆绑在一起:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MVCProject.Models.ViewModels.Service { public class ServiceViewModel : ViewModel { public List<SelectListItem> IsMultipleServicers { get; set; } } }
这是我的行动:
[AcceptVerbs(HttpVerbs.Get)] public virtual ActionResult Service() { return View(new ServiceViewModel() { IsMultipleServicers = BuildBooleanSelectList(true) }; } private List<SelectListItem> BuildBooleanSelectList(bool isTrue) { List<SelectListItem> list = new List<SelectListItem>(); if (isTrue) { list.Add(new SelectListItem() { Selected = false, Text = "No", Value = "false" }); list.Add(new SelectListItem() { Selected = true, Text = "Yes", Value = "true" }); } else { list.Add(new SelectListItem() { Selected = true, Text = "No", Value = "false" }); list.Add(new SelectListItem() { Selected = false, Text = "Yes", Value = "true" }); } return list; }
我认为问题是关于DropDownList
重载的一个混淆:
-
Html.DropDownList(string name)
查找Html.DropDownList(string name)
的视图模型属性,并键入IEnumerable<SelectListItem>
。 它将使用列表中选定的项目(SelectListItem.Selected == true
),除非有相同名称的表单后期值。 -
Html.DropDownList(string name, IEnumerable<SelectListItem> selectList)
使用来自selectList
的项目,但不使用它们的选定值。 通过在视图模型(或发布数据)中parsingname
并将其与SelectListItem.Value
匹配来find所选内容。 即使该值无法find(或为null),它仍然不会使用SelectListItems列表中的选定值。
您的代码使用第二个重载,但是指定了不存在的“value”属性(“MultipleServicers”)。
要解决您的问题,请使用第一个重载:
<%= Html.DropDownList("IsMultipleServicers") %>
或者,将string MultipleServicers
属性添加到您的视图模型并将其填充到您的控制器中。 我推荐这个解决scheme,因为它解决了初始显示,后显示和将发布数据映射到视图/后期模型的几个问题:
public class ServiceViewModel : ViewModel { public string MultipleServicers { get; set; } public List<SelectListItem> IsMultipleServicers { get; set; } }
然后为您的HTML:
<%= Html.DropDownList(Model.MultipleServicers, Model.IsMultipleServicers) %>
该技术也映射到MVC2中:
<%= Html.DropDownListFor(x => x.MultipleServicers, Model.IsMultipleServicers) %>
我遇到了同样的问题,使用Html.DropDownList(string名称,IEnumerable selectList)重载。 看起来我的模型具有与下拉列表名称相同名称的属性。 在这种情况下,MVC赞成我的模型的属性值超过IEnumerable中每个条目的Selected属性。
解决scheme是使用与名称不匹配的下拉列表的名称。 另一个解决scheme是编写我自己的扩展方法,忽略模型和视图状态,而是始终遵守选定的属性。
DropDownList帮助器从模型中提取默认值。 在第一种情况下,与名称相对应的模型中的值是一个SelectList – 它不与列表中的任何项目匹配,它是列表,因此没有select任何值。 在第二个示例中,您的模型不包含具有该名称的属性,因此模型中的值不能使用,并且默认为SelectList本身中指定的状态。 通常情况下,我将在模型上为所选值设置一个属性 – 这将成为默认值 – 另一个属性表示列表的潜在值。