在EditorTemplate中的DropDownListFor不select值

我有一个自定义对象的编辑器模板。 在那个编辑器模板里面,我使用了几个DropDownListFor帮助器。 在他们每个人中,我指定一个独特的模型属性(具有预先选定的值)和包含所有select选项的select列表。

例:

<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> 

我知道选项值正在填充(从查看源),并且我的模型被传入正确的ID值(DocumentCategoryType)。

呈现视图时,下拉列表中没有选定的项目,因此它默认为第一个(未选定的)值。

有没有人有任何想法?

谢谢。

我们还通过填充一个新的SelectList来解决这个问题,该SelectList具有相应的SelectListItem选项,但是创build了这个扩展方法来保持对DropDownListFor的调用。

 public static SelectList MakeSelection(this SelectList list, object selection) { return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection); } 

然后你的DropDownListFor调用变成:

 <%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %> 

通过ASP.NET MVC 2源代码展示了这个问题的一些解决scheme。 从本质上讲, SelectListItem中的SelectListSelected属性设置为true的helper扩展方法中传递,不会影响使用为该item selected属性所呈现的<option>元素。

<option>元素上的selected属性由<option>确定

1)检查助手扩展方法是否通过了SelectList 。 如果这个值为null,那么框架将在ViewData中查找对应于您希望呈现其下拉列表的视图模型属性的键的值。 如果该值是一个SelectList ,那么只要模型属性的模型状态为null,这将用于呈现<select>包括取任何选定的值。

2)如果在助手扩展方法中传递了SelectList ,并且model属性的模型状态为null,则框架将使用模型属性名称作为键在ViewData中查找默认值。 视图数据中的值被转换为一个string,并且传递给辅助方法扩展方法的SelectList中的所有与默认值匹配的值(如果没有设置值,那么文本将被选中)将具有Selected属性设置为true,这反过来将呈现具有selected="selected"属性的<option>

综合起来,有两个合理的选项,我可以看到select一个选项,并使用强types的DropDownListFor

使用以下视图模型

 public class CategoriesViewModel { public string SelectedCategory { get; private set ; } public ICollection<string> Categories { get; private set; } public CategoriesViewModel(string selectedCategory, ICollection<string> categories) { SelectedCategory = selectedCategory; Categories = categories; } } 

选项1

在控制器中的ViewData中设置一个值,使您的视图与用于呈现下拉列表的集合的属性名称保持一致

控制器的行动

 public class CategoriesController { [HttpGet] public ViewResult Select() { /* some code that gets data from a datasource to populate the view model */ ICollection<string> categories = repository.getCategoriesForUser(); string selectedCategory = repository.getUsersSelectedCategory(); CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories); this.ViewData["Categories"] = selectedCategory; return View(model); } [HttpPost] public ActionResult Select(CategoriesViewModel model) { /* some code that does something */ } } 

并在强types的看法

 <%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %> 

选项2

使用所选项目的属性名称呈现下拉菜单

控制器的行动

 public class CategoriesController { [HttpGet] public ViewResult Select() { /* some code that gets data from a datasource to populate the view model */ ICollection<string> categories = repository.getCategoriesForUser(); string selectedCategory = repository.getUsersSelectedCategory(); CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories); return View(model); } [HttpPost] public ActionResult Select(CategoriesViewModel model) { /* some code that does something */ } } 

并在强types的看法

 <%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %> 

它被确认为一个错误@ aspnet.codeplex.com,只对强types的视图行为。

解决方法:在视图代码中填充您的SelectList

喜欢

 <%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) => 

呸。 我最终解决了这个问题。 我希望这被RTM固定。

  <%if(Model!=null){ %> <%= Html.DropDownListFor(m => m.DocumentCategoryType, new SelectList(Model.DocumentCategoryTypeList,"Value","Text", Model.DocumentCategoryType))%> <%}else{%> <%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> <%}%> 

确保在将其发送到视图时将值分配给m.DocumentCategoryType。

一般来说,这个值会在你做回发时被重置,所以你只需要在返回到你的视图时指定值。

当创build一个下拉列表,你需要传递它的两个值。 1.这是您将存储选定值的位置2.是实际列表

 <%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> 

我犯了错误的设置select列表项目select值为True。 这不会做任何事情。 相反,只需在控制器中为m.DocumentCategoryType赋值,这实际上会为您select。

如果下拉列表的来源是IEnumerable而不是SelectList,那么这里有另一个好的解决scheme:

 public static SelectList MakeSelection(this IEnumerable<SelectListItem> list, object selection, string dataValueField = "Value", string dataTextField = "Text") { return new SelectList(list, dataValueField, dataTextField, selection); } 
 Model.DocumentCategoryTypeList 

这可能是你的问题。 在SelectListItems上,是否将值设置为.ToString()输出?

  var list = new List<SelectListItem>() { new SelectListItem() { Value = Category.Book.ToString(), Text = "Book" }, new SelectListItem() { Value = Category.BitsAndPieces.ToString(), Text = "Bits And Pieces" }, new SelectListItem() { Value = Category.Envelope.ToString(), Text = "Envelopes" } }; 

这样做后为我工作。 它只需要能够匹配来自对象的值

我设法解释同样的问题说folling:

 new SelectList(sections.Select(s => new { Text = s.SectionName, Value = s.SectionID.ToString() }), "Value", "Text") 

这个技巧将转换为一个string的值。 我知道这已经在前面的答案中提到,但我觉得我的解决scheme有点清洁:)。 希望这可以帮助。

从我的项目中复制了na:

 <%= Html.DropDownListFor(m => m.Profession.Profession_id, new SelectList(Model.Professions, "Profession_id", "Profession_title"),"-- Profession --")%> 

通过的模型:

  ... public Profession Profession { get; set; } public IList<Profession> Professions { get; set; } ... 

生成的Html:

  <select id="Profession_Profession_id" name="Profession.Profession_id"> <option value="">-- Profesion --</option> <option value="4">Informatico</option> <option selected="selected" value="5">Administracion</option> </select> 

为我工作。 我有这样的forms,唯一的缺点是,如果模型是无效的,我将模型返回到视图,我不得不重新加载专业列表。

 obj.Professions = ProfileService.GetProfessions(); return View(obj); 

我也有一个字段ProgramName这个问题。 原来,我们在BaseController和Layout.cshtml中使用了ViewBag.ProgramName,这是为了不同的目的。 由于ViewBag.ProgramName中的值未在下拉列表中find,因此即使SelectListItem.Selected对列表中的一个项目为true,也没有select任何值。 我们只是将ViewBag更改为使用不同的键,问题已解决。

这里是一个DropDownDownListForreplace ,只是从原来的MVC来源略有不同。

例:

 <%=Html.FixedDropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> 

我很担心制作这么多的selectList的副本,所以相反,我添加selectedvalue作为自定义属性,然后使用jquery实际执行项目select:

 @Html.DropDownListFor(item => item.AttendeeID, attendeeChoices, String.Empty, new { setselectedvalue = Model.AttendeeID }) ........ jQuery("select[setselectedvalue]").each(function () { e = jQuery(this); e.val(e.attr("setselectedvalue")); });