One thing that I’m not particularly fond of in ASP.NET MVC is figuring out where to put additional data one needs for views. If one is using a “model per view” approach it is simple — stick it in that model. Otherwise you can choose to add it to a model that won’t always need it or pass it via ViewBag/ViewState. I currently lean towards the last option.
The other annoyance is how best to transform a list of objects into a IEnumerable<SelectListItem> collection cleanly with the special case of handling a default value. I have started to approach this with extension methods and am very happy with how it is working.
Transforming your List<MyObject> to IEnumerable<SelectListItem>
Our current data tier has a manager class for each object type. When that object type is going to be used in a select list, I add an extension to IEnumerable<MyObject> like so:
public static class MyObjectManagerExtensions
{
public static IEnumerable AsSelectList(this IEnumerable list, int? value)
{
return (from item in list
select new SelectListItem
{
Selected = value.HasValue && item.Id == value.Value,
Text = item.Name,
Value = item.Id.ToString()
});
}
}
To support the option of a default value, I have an extension method that applies to IEnumerable
public static class SelectListExtension
{
public static IEnumerable WithDefault(this IEnumerable list, string defaultLabel = "Select one...", string value = "")
{
return (new[] { new SelectListItem { Text = defaultLabel, Value = value } }).Concat(list);
}
}
Here is an example of an actually call to this methods in:
ViewBag.MyObject = myObjectManager
.GetAllMyObjectBy(isForFoo: true, orderBy: MyObjectColumns.Name)
.AsSelectList(myObjectId)
.WithDefault();