score:6

Accepted answer

There are two options:

If you can implement an interface on the entity

public interface ISelectable
{
    string Name { get; }
    int Id { get; }
}
public static List<SelectListItem> ToSelectItemList<T>(this IEnumerable<T> collection)
    where T: ISelectable
{
    return collection.Select(m => new SelectListItem
    {
        Text = m.Name,
        Value = m.Id.ToString()
    }).ToList();
}

Using delegates

public static List<SelectListItem> ToSelectItemList<T>(this IEnumerable<T> collection, Func<T, string> nameGetter, Func<T, int> idGetter)
{
    return collection.Select(m => new SelectListItem
    {
        Text = nameGetter(m),
        Value = idGetter(m).ToString()
    }).ToList();
}

Usage :

m.EmploymentStatus.ToSelectItemList(e => e.Name, e => e.Id);

The second option is more verbose to use, but you get a ton more flexibility, since you don't have to clutter your data model with useless interface implementation, and you are free to use any property names for Name or Id

score:8

You can define an interface for all entities that you are going to use for DropDownLists like

public interface IDropDownItem
{
   int Id {get; set;}
   string Name {get; set;}
}

then

public static List<SelectListItem> ToSelectItemList<T>(IEnumerable<T> collection) 
   where T : IDropDownItem
{
    return collection.Select(m => new SelectListItem
    {
        Text = m.Name,
        Value = m.Id.ToString()
    }).ToList();
}

It would be better to make ToSelectItemList as extension method:

public static class EnumerableExtensions
{
    public static List<SelectListItem> ToSelectItemList<T>(this IEnumerable<T> collection)
        where T : Program
    {
        return collection.Select(m => new SelectListItem
        {
            Text = m.Name,
            Value = m.Id.ToString()
        }).ToList();
    }
}

score:3

DropDownListFor requires a IEnumerable<SelectListItem> selectList as a collection

There's already a class for that, namely SelectList:

var selectListItems = new SelectList(items, "Id", "Name");

No need for new extension methods whatsoever. I thought SelectList() also has an overload with expressions for the key/value members instead of strings, but I may have found that somewhere else.

See also ASP.NET MVC Dropdown List From SelectList.


Related Articles