DropDownList sets the selected item in asp.net MVC

I noticed that it seems to me an error in asp.net MVC or just that I am doing something wrong. I am currently using 1.0, so maybe this is what will be covered in version 2.0. But anyway, we go.

When my view model has a property whose name matches the declared identifier for the drop-down list, the selected item is ignored and the displayed html did not select anything. Not sure if I did something wrong, but changing the identifier name fixes the problem. I simplified the example, I hope this is understandable, otherwise, please let me know.

Here is my view where the declared identifier matches my list in the model:

<table border="0" cellpadding="0" cellspacing="0"> <tr> <td> <%= Html.DropDownList("IsMultipleServicers", Model.IsMultipleServicers) %> </td> </tr> </table> 

And provided by 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> 

Now make a small change. I will change the declared identifier to something else.

Here is my view:

 <table border="0" cellpadding="0" cellspacing="0"> <tr> <td> <%= Html.DropDownList("MultipleServicers", Model.IsMultipleServicers) %> </td> </tr> </table> 

And now html rendered:

 <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> 

Note that now I get the selected option, which will be the second item in the list.

Here is my ViewModel just to bind everything together:

 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; } } } 

Here is my action:

 [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; } 
+26
drop-down-menu asp.net-mvc
Mar 09 '10 at 16:17
source share
3 answers

I think the problem is the confusion regarding DropDownList overloads:

  • Html.DropDownList(string name) searches for the view model property name and enter IEnumerable<SelectListItem> . It will use the selected element ( SelectListItem.Selected == true ) from the list, if only one message about the form value is not specified.

  • Html.DropDownList(string name, IEnumerable<SelectListItem> selectList) uses elements from selectList , but not their selected values. The selected one is found by resolving name in the view model (or post data) and matching it with SelectListItem.Value . Even if the value cannot be found (or equal to null), it still will not use the selected value from the SelectListItems list.

Your code uses a second overload, but indicates a property "value" that does not exist ("MultipleServicers").

To fix your problem, use the first overload:

 <%= Html.DropDownList("IsMultipleServicers") %> 

Or add the string MultipleServicers property string MultipleServicers to your view model and populate it in your controller. I would recommend this solution because it faces a number of problems with the initial display, display of messages and display of message data in a view / publish model:

 public class ServiceViewModel : ViewModel { public string MultipleServicers { get; set; } public List<SelectListItem> IsMultipleServicers { get; set; } } 

Then for your HTML:

 <%= Html.DropDownList(Model.MultipleServicers, Model.IsMultipleServicers) %> 

This method is also displayed in MVC2:

 <%= Html.DropDownListFor(x => x.MultipleServicers, Model.IsMultipleServicers) %> 
+43
Mar 09 '10 at 16:26
source share

I ran into the same problem using the Html.DropDownList overload (string name, IEnumerable selectList). It looks like my model has a property with the same name as the drop-down list name. In this case, MVC approved the value of the property of my model over the Selected property of each entry in IEnumerable.

The solution was to use a name for the drop-down list that does not match the property name. Another solution would be to write my own extension method, which ignores the state of the model and view, and instead always respects the selected property.

+9
Mar 09 '10 at 21:07
source share

The DropDownList helper retrieves the default value from the model. In the first case, the value in the model corresponding to the name is SelectList - this does not correspond to any of the elements in the list, this is a list, so no value is selected. In the second example, your model does not include a property with this name, so the value from the model cannot be used, and by default it corresponds to the state specified in the SelectList itself. Typically, I will have a model property for the selected value - this becomes the default value - and another property that represents the potential values ​​for the list.

+2
Mar 09 '10 at 16:26
source share



All Articles