Fixing MVC 3 Html.DropDownListFor selected item
Posted By Mike Bender / 13th February 2012
I recently ran into an issue with when using the SqlFunctions.StringConvert function (as required by LINQ to cast scalars to a string). What I didn’t realize at first is that the StringConvert function pads the string that it casts to. As it turns out this causes some issues with defining a selected item in the list.
To best describe this issue it is probably best to quickly walk through an example of how I ran into this and resolved it.
The Problem
The editor is to provide a drop down list of available options for a given property on the Entity being edited. In my case this was a POCO being used with the Entity Framework. Straight forward enough. I started with the following in my view model.
public class foo
{
public MyObject MyObject { get; private set; }
public List MyObjects{ get; private set; }
public foo(int id){
this.MyObject = MyObjectRepository.GetById(id);
this.MyObjects = (from c in MyObjectRepository.All
where c.Id != id
select new SelectListItem {
Text = c.Name,
Value = SqlFunctions.StringConvert((double)c.Id)
})
.ToList());
}
}
In my view I had the following code.
@Html.DropDownListFor(m=>m.MyObject.ParentID, Model.MyObjects)
MyObject has a property that references its parent, if it has one. This is the trigger for our selected item.
Upon running this code I quickly noticed that the parent was not being selected. I looked and the LINQ statement was getting the correct ID’s and the ParentID was correct. So what was happening?
Well as it turns out the StringConvert functions casts the Id to a padding string and adding a call to the Trim function fixed everything. This is definitely a bit clunky in my opinion. Why did the LINQ team not let us simply cast our scalars using the ToString function?
Well that is it, below is the final LINQ statement that worked for me.
this.MyObjects = (from c in MyObjectRepository.All
where c.Id != id
select new SelectListItem {
Text = c.Name,
Value = SqlFunctions.StringConvert((double)c.Id).Trim()
})
.ToList());