Old school data binding for List controls in ASP.NET MVC

The ASP.NET MVC is designed for Performance and extensibility and testability in mind. MVC 1.0 comes with handful of HTML extensions that allows you render textboxes, dropdowns and other controls. While you are creating a DropDownList or List box you may require this little extension to bind your control to existing data source such as Linq2Sql or dataset.

For an example :

 <%= Html.DropDownList("jobcategory", Model.JobCategory)%>
 
 Error 2 Argument '3': cannot convert from 'JobCategoryDataTable' to 
'System.Collections.Generic.IEnumerable' d:\Projects\ShellMvc2\Views\Search\SearchControls.ascx 11 46 ShellMvc2 

where Model.JobCategory is the Linq2Sql object collection. I wonder if it was ASP.NET I had DataTextField and DataValueField.

Here we go with custom list extension:

 <%= Html.DropDownList("jobcategory", Model.JobCategory.ToSelectList("JobCategoryId", "JobCategory")%>

Where Model.JobCategory is the data source, this can be any type of IEnumerable source such as IDataReader, DataTable, List2Sql or any CustomObject collection.

First parameter JobCategoryId is the DataDisplayField and the second parameter is the DataValueField. This extension can further be improved by creating custom of IEnumerator<SelectListItem>

 using System.Collections;
 using System.Collections.Generic;
 using System.Web.Mvc;
 using System.Web.UI;
 public static class MyExtensions
 {
     public static IEnumerable<SelectListItem> ToSelectList(this IEnumerable collection, string displayField, string valueField)
     {
         return ToSelectList(collection, displayField, valueField, null);
     }
  
     public static IEnumerable<SelectListItem> ToSelectList(this IEnumerable collection,
                            string displayField, string valueField, string selectedValue)
     {
         List<SelectListItem> list = new List<SelectListItem>();
         foreach (var item in collection)
         {
             string value = DataBinder.GetPropertyValue(item, valueField).ToString();
             list.Add(new SelectListItem
             {
                 Text = DataBinder.GetPropertyValue(item, displayField).ToString(),
                 Value = value,
                 Selected = (value.Equals(selectedValue))
             });
         }
         return list;
     }
 }