2
votes

I am trying to use the Html.ListBoxFor helper to show a list box and return the selected Id. Is there a problem with the dataValueField not being a string?

If the SelectList contained in the model uses integers as the dataValueField then I get a "Value cannot be null - Parameter name: Source" exception raised when the list is rendered in the view.

If the Id is changed to a string then everything works and the selected Id is passed back to the view.

Any ideas?

Here is the controller (based on a cut down new project)

namespace Mvc2.Controllers
{
    public class ViewModel
    {
        public int TestId { get; set; } // if this is a string it works ok
        public SelectList ListData {get; set;}
    }

    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new ViewModel();
            model.TestId = 1; // code corrected after Lazarus' comment

            var lst = new[] { new { Id = 1, Name = "cat" }, new { Id = 2, Name = "dog" } };
            model.ListData = new SelectList(lst, "Id", "Name");

            return View("TestView", model);
        }

        public ActionResult TestSubmit(ViewModel returnedModel)
        {
            int i = 99; // break here - returnedModel has correct TestId when declared as string
        }
    }
}

here is the View - crashes on the ListBoxFor line

<%using (Html.BeginForm("TestSubmit", "Home")) { %>

    <%=Model.TestId %><br />
    <%=Html.ListBoxFor(m => m.TestId, Model.ListData) %>

    <br />
    <input type="submit" value="Save" />

<%} %>
3

3 Answers

3
votes

The expression you are passing for the selected values needs to be IEnumerable because ListBoxFor supports multiple selected items.

2
votes

Answering my own question;

I am unconviced by the comments that this might be a bug which is waiting to be fixed because I get it in RC2 and in MVC 1 (I copied the code back to a project in that release). Anyway I have implemented a work around for now which is to:-

(a) Add a dummy string version of the Id to the model (TestId)

public class ViewModel
{
    public string TestId { get; set; } // dummy Id as a string
    public List<DataToShow> Data { get; set; }
    public SelectList ListData {get; set;}
}

(b) Display the list but retrieve the value as the dummy TestId - note that the list still dumps the data values as integers!

<%=Html.ListBoxFor(m => m.TestId, Model.ListData) %>

(c) Copy the dummy string value into its proper integer location in the action

public ActionResult TestSubmit(ViewModel returnedModel)
{
    MyModel.DataId = Int32.Parse(returnedModel.TestId);

Hope this is of some Help.

1
votes

This is a known issue with ASP.NET MVC 2. It should be fixed in the March release.