Create Html.DropdownListFor without magic strings

By | 2011-09-20

Using magic strings are bad practice. Changes could lead to code compiling but containing lots of errors (appearing during runtime). And refactoring your code is a lot harder if you have to globally search and replace.

Using dropdown lists with ASP.NET MVC has a Html-helper that wants you to use magic strings. Having a Category class:

    public class Category
        public int CategoryId { get; set; }
        public string Name { get; set; }

And a viewmodel:

    public class DropdownViewModel
        public int CategoryId { get; set; }
        public Category[] Categories { get; set; }


You would then use the html-helper like this:

    public static class ExtensionMethods
        public static IEnumerable<SelectListItem> ToSelectList<TItem, TValue>(this IEnumerable<TItem> enumerable, Func<TItem, TValue> value, Func<TItem, string> text, string defaultText = null, string defaultValue = null)
            var itms = enumerable.Select(f => new SelectListItem { Text = text(f), Value = value(f).ToString() }).ToList();
            if (defaultText != null)
                itms.Insert(0, new SelectListItem { Text = defaultText, Value = defaultValue ?? "0" });
            return itms;

Now it’s easy to just use lambdas and, this little extension method has a couple of overloads.

Html.DropDownListFor(m => m.CategoryId, 
    Model.Categories.ToSelectList(f => f.CategoryId, f => f.Name))

Usage is really easy, just use the extension method on the Array you wish to create a dropdown items from.

Now your code is refactor safe

First parameter: Selected item in model

Second parameter: Id/value-item (generic TValue, so you can use for example int’s without calling ToString()

Third parameter: Text to display for each item in dropdown

Fourth parameter(optional): Empty default-text (first item in dropdown), uses value “0″ if fifth parameter isn’t supplied

Fifth parameter(optional): Empty default-value

Category: C#

Leave a Reply

Your email address will not be published. Required fields are marked *