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重载的一个混淆:

  1. Html.DropDownList(string name)查找Html.DropDownList(string name)的视图模型属性,并键入IEnumerable<SelectListItem> 。 它将使用列表中选定的项目( SelectListItem.Selected == true ),除非有相同名称的表单后期值。

  2. 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本身中指定的状态。 通常情况下,我将在模型上为所选值设置一个属性 – 这将成为默认值 – 另一个属性表示列表的潜在值。