The DropDownList html helper differs a bit from the standard Html helper methods, and, not surprisingly, the way it works is one of the questions I get asked the most. So in this post I’m going to dissect this method, and show you how to use it.
Standard Html Helpers
One of the cool features of ASP.NET MVC is the automatic binding of html form fields: all the Html helper methods will auto-magically take the default value of the form field directly from the ViewData or the view model object with the same name of the control.
Calling the TextBox helper method:
<%= Html.TextBox("Name") %>
will results, if the view model supplied contained the property Name, in the following HTML:
<input id="Name" name="Name" type="text" value="Simone" />
It would have been the same as calling the other helper overload, which specifies both the name and the value:
<%= Html.TextBox("Name", Model.Name) %>
Introducing the DropDownList helper
But things get a bit more complex when it comes to the HTML Select element, which most ASP.NET developers know as DropDownList. This control needs two values to be retrieved from the ViewData: the list of items to be displayed in the drop down, and the item that needs to be pre-selected, so the code to set it up is a bit more complex.
The automatic binding of the other html helpers still works but, since it can bind only one thing at the time, depending on your preferences you have and the scenario you are facing, you have to decide whether you want to automatically bind the list item or the selected item.
The method signature
Let’s have a look at the method signature:
and the meaning of the parameters:
- name – the name of the HTML select element, and also the name of the view model property that is bound to the element
- selectList – the list of options of the select list
- optionLabel – the text that will be added at the top of the select list. Usually something like “Select …”
- htmlAttributes – this is in common with all the other html helper. A dictionary or an anonymous type with the html attributes you want to add to the HTML element
All the parameters except the first one are optional: if only the name is provided, the helper will automatically bind the list item. Otherwise if both the name and selectList are provided, the select item will be bound, and the select list will be the one supplied with the parameter. You’ll see how to adopt each approach later.
But now let’s have a look at the presentation model class used to represent the drop down list with its options: SelectListItem.
This class has three properties:
- string Text – the string that will be displayed as text of the option
- string Value – the string that will be used as the value of the option
- bool Selected – whether the option is selected
How to write a DropDownList
Let’s now have a look at the two possible way of building a DropDownList.
Autobinding the ItemList
The first approach consists in setting up the whole list of items in the controller, specifying also which options must be the selected item.
List<SelectListItem> items = new List<SelectListItem>();
Text = "Swimming",
Value = "1"
Text = "Cycling",
Value = "2",
Selected = true
Text = "Running",
Value = "3"
As you can see, you set the text and value for each option, and set Selected = true for the item you want to be selected. And then you call the helper, specifying only the name: this will be the name of the select element, and must be the same name of the property of the view model that contains the list of items (in the sample named ListItems).
<%= Html.DropDownList("ListItems") %>
But in case you are caching the list of items or are retrieving them separately from the item that must be selected this is not the best solution.
Autobinding the selected item
The other approach is to automatically bind the selected item, and passing the list of items as parameter to the DropDownList helper method.
In the controller you do exactly the same thing as before, just don’t set to true the Selected property of any item. Then you also have to put into the view model the value of the item you want to select.
var model = new IndexViewModel()
ListItems = items,
SelectedItem = 2
And finally in the view, you use the overload which accepts also the selectList parameter:
<%= Html.DropDownList("SelectedItem", Model.ListItems) %>
The only difference in the HTML rendered is that, with first approach, the name of the HTML select element is “ListItems”, with the second it is “SelectedItem”.
These approaches are fine if you are creating your own list, but they are not the optimal solution if you are receiving the list of options for an external method, for example from a DB repository.
Using the SelectList helper class
To address the latest scenario the ASP.NET MVC framework comes with a class that helps you build the list of items in a way that can be accepted by the DropDownList html helper: it’s called SelectList.
This class encapsulates all the information needed to create a list of SelectListItem:
- Items – any IEnumerable containing the list of items that needs to be in the select element
- DataTextField and DataValueField – the names of the properties that will be used as text and as value of the item
- SelectedValue – the value of the selected item
Using this you can take any list of objects and turn it into a list of SelectListItem
//with selected value specified
var selectItems = new SelectList(brands, "BrandId", "BikeBrand", 2);
//only the items list
var selectItems = new SelectList(brands, "BrandId", "BikeBrand");
And you can use it either specifying the selected value in the controller, and using the overload with just the name parameter, or specifying the selected value as additional property in the view model and using the overload that takes both the name and the selectList property (same as the first two approaches).
In this post we dissected the DropDownList API, and you saw the different possible approaches to writing a dropdown list:
- Specifying all the info needed (list of options and selected option) inside a List of SelectListItem and passing it to view: this is a good solution if you build the list and you can set the selected item at the same time and in the same process
- Put the list of options as a List of SelectListItem and the Selected Item in two separate properties of the view model: this approach is better if you build the list and retrieve the selected item in different moment and/or in different processes
- Use the SelectList helper class to create the needed list: use this approach if you receive the list of items for a external library and you don’t want to manually cycle over it to create the List of SelectListItem
Hope this post helped clearing up a bit the confusion that I saw around the DropDownList helper method.
For a more samples about creating a DropDownLists with ASP.NET MVC, and all other HtmlHelper, I'd recommend the book I wrote about ASP.NET MVC, titled Beginning ASP.NET MVC 1.0, published by Wrox