views:

61

answers:

2

I'm having problems with the helper Html.ListBoxFor().

Here is my ViewModel:

public class NewReservation
{
    public SelectList AvailableServiceDates { get; set; }
    public DateTime SelectedServiceDate { get; set; }
}

Here is my action method:

    public virtual ActionResult New()
    {
        NewReservation newReservation = new NewReservation();
        newReservation.AvailableServiceDates = new SelectList(nhSession.Linq<Service>().Select(x => x.DateTime).Distinct());
        return View(newReservation);
    }

And in my view:

<%:Html.ListBoxFor(x => x.SelectedServiceDate, Model.AvailableServiceDates) %>

Here is the exception:

Value cannot be null. Parameter name: source

Stack Trace:

[ArgumentNullException: Value cannot be null. Parameter name: source]
System.Linq.Enumerable.Cast(IEnumerable source) +4177011
System.Web.Mvc.Html.SelectExtensions.SelectInternal(HtmlHelper htmlHelper, String optionLabel, String name, IEnumerable1 selectList, Boolean allowMultiple, IDictionary2 htmlAttributes) +723
System.Web.Mvc.Html.SelectExtensions.ListBoxHelper(HtmlHelper htmlHelper, String name, IEnumerable1 selectList, IDictionary2 htmlAttributes) +47
System.Web.Mvc.Html.SelectExtensions.ListBoxFor(HtmlHelper1 htmlHelper, Expression1 expression, IEnumerable1 selectList, IDictionary2 htmlAttributes) +113
System.Web.Mvc.Html.SelectExtensions.ListBoxFor(HtmlHelper1 htmlHelper, Expression1 expression, IEnumerable`1 selectList) +85
ASP.views_reservation_new_aspx.__RenderMainContent(HtmlTextWriter __w, Control parameterContainer) in c:\code\GTCC Culinary Reservation\src\CulinaryReservation.WebMVC\Views\Reservation\New.aspx:11 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Control.Render(HtmlTextWriter writer) +10
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
ASP.views_shared_site_master._Render_control1(HtmlTextWriter __w, Control parameterContainer) in c:\code\GTCC Culinary Reservation\src\CulinaryReservation.WebMVC\Views\Shared\Site.Master:66 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Control.Render(HtmlTextWriter writer) +10
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Page.Render(HtmlTextWriter writer) +29
System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +56
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060

This post describes the same problem. And like that post, if I change my NewReservation.SelectedServiceDate from DateTime to string, things seem to work. But everything I have read indicates this is a bug that should have been fixed in an MVC2 release candidate.

Am I doing something wrong? I don't want the property's type to be string, it needs to be DateTime. Shouldn't I be able to use objects that reflect my problem?

+1  A: 

A multiple select list could be empty (for example if the user makes no selection) meaning that you cannot bind to a value type (like DateTime). You could use a nullable DateTime instead:

public class NewReservation
{
    public SelectList AvailableServiceDates { get; set; }
    public DateTime? SelectedServiceDate { get; set; }
}

Also notice that in a multiple select list the user could perform multiple selections meaning that binding to a single date doesn't look very natural. IMHO it would be more natural to have this:

public class NewReservation
{
    public SelectList AvailableServiceDates { get; set; }
    public IEnumerable<DateTime> SelectedServiceDates { get; set; }
}
Darin Dimitrov
Changing the property to DateTime? worked. I don't want to allow multiple selections, so I changed to DropDownListFor() and passed in a size attribute.
Ronnie Overby
@Ronnie, what you are looking for doesn't have an equivalent tag in HTML. In a `select` tag if you don't have the `multiple` attribute you can select a single option (renders as drop down), if you set the `multiple` tag, no matter to what value (even empty) you get a list box where you can always select multiple values. So, if you want a single selection use `Html.DropDownListFor`. Reference: http://www.w3.org/TR/html401/interact/forms.html#adef-multiple
Darin Dimitrov
+1  A: 

Hey,

Try setting the SelectedServiceDate to something in your action method like DateTime.Now or something recent and see if that resolves the issue... No date is being assigned, so that's DateTime.MinValue.

Brian