MVC2 Bug on Data Binding in Listbox?

Seems MVC and MVC 2 don’t realize that there is an issue when binding the data on the view:

Given an extension on HtmlHelper: this extension will generate a list box in view based on the collection “cakes”. (Because I like cake, so I use dessert object as example :)

public static MvcHtmlString MyDropDownList(this HtmlHelper target, string controlName, IQueryable<Cake> cakes, object htmlAttr)
{
if (cakes== null)
return MvcHtmlString.Empty;
var cakesList = new SelectList(cakes, “Id”, “CakesName”);
return target.ListBox(controlName, cakesList, htmlAttr);
}

It is okay, but the main issue is if the when I specify the Model data on control name, it IS SUPPOSED to generate the list box with the data which retrieved from database are selected. Yes.  IT IS SUPPOSED TO BE. But, unfortunately, MVC fail to automatically bind data for us…  The data “cakesList” is showing properly, but with no preselect options. In most of the business logic, it’s not gonna work, because it is no point for user to re-select the options every time before save the data.

In this case, MVC is not gonna auto-bind the data for us, we just need to figure out another way to display and manipulate the data properly. So we will change something on the extension, view and the controller:

1. On the view, don’t specify the name to model’s name, For example, the data which will be weaved to list box is CakeViewData.CakeList, the data related to database is CakeViewData.Dessert.Cakes. Normally, we will use the extension to weave the data:

<%=Html.MyDropDownList(“Dessert.Cakes”, Model.CakeList, new { @class = “multiselect”, size = 5 })%>

Since MVC is not gonna take care of the data binding, The name (on parameter controlName) should and NEED to use other name instead. Change “Cakes” to any other name, for example, change to “MyCakes”:

<%=Html.MyDropDownList(“Dessert.MyCakes”, Model.CakeList, new { @class = “multiselect”, size = 5 })%>

2. Extension is changed to:

public static MvcHtmlString MyListBoxWithSelectedList(this HtmlHelper target, string name, IQueryable<Cake> cakes, List<string> selected, object htmlAttr)
{
if (interests == null)
return MvcHtmlString.Empty;
var cakeList = new MultiSelectList(cakes, “Id”, “CakeName”, selected);
return target.ListBox(name, cakeList, htmlAttr);
}

I just add a parameter “List<string> selected” in the extension which will be used in MultiSelectList object that can be bind to the the items to be selected.

3. In controller, before saving the data, need to use FormCollection or Request["Dessert.MyCakes"] to obtain the data “MyCakes” manually.

string myCakes = Request["Dessert.MyCakes"];
Dessert dessert = new Dessert{Cake = myCakes};

It might not be a bug actually. And in this example you can feel how flexibility that MVC can bring you: the way to manipulate the model or data varies!  :)

Happy programming in MVC 2!

3 thoughts on “MVC2 Bug on Data Binding in Listbox?”

  1. This is a great website. I have already been back repeatedly within the last few days and wish to register for your rss implementing Google but can’t find out the way to do it accurately. Do you know of any sort of tutorials?

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">