tags:

views:

69

answers:

2

I am trying to populate a dropdown list from a database mapped with Linq 2 SQL, using ASP.NET MVC 2, and keep getting this error.

I am so confused because I am declaring a variable with the type IEnumerable<SelectListItem> on the second line, but the error makes me think this is not the case. I feel like this should be very simple, but I am struggling. Any help is appreciated.

Here are the interesting bits of my controller:

public ActionResult Create()
    {
        var db = new DB();
        IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(b => new SelectListItem { Value = b.basetype, Text = b.basetype });
        ViewData["basetype"] = basetypes;
        return View();
    }

And here are the interesting bits of my view:

            <div class="editor-label">
            <%: Html.LabelFor(model => model.basetype) %>
        </div>
        <div class="editor-field">
            <%: Html.DropDownList("basetype") %>
            <%: Html.ValidationMessageFor(model => model.basetype) %>
        </div>

Here is the Post action when submitting the Form

        // POST: /Meals/Create

    [HttpPost]
    public ActionResult Create(Meal meal)
    {
        if (ModelState.IsValid)
        {
            try
            {
                // TODO: Add insert logic here
                var db = new DB();
                db.Meals.InsertOnSubmit(meal);
                db.SubmitChanges();
                return RedirectToAction("Index");
            }

            catch
            {
                return View(meal);
            }
        }

        else
        {
            return View(meal);
        }
    }

Thanks.

A: 

You are setting the collection as an item in ViewData dictionary and trying to retreive it as property on the model. A simple fix would be to reference it the same way as you set it:

    <%var basetype = ViewData["basetype"] as IEnumerable<SelectListItem>;%>
    <div class="editor-label">
        <%: Html.Label("basetype") %>
    </div>
    <div class="editor-field">
        <%: Html.DropDownList("basetype", basetype) %>
        <%: Html.ValidationMessage("basetype") %>
    </div>

Alternatively, the below code uses a strongly typed view:

public class ViewModel {
   //Model properties
   public IEnumerable<SelectListItem> basetype {get;set;}
}

public ActionResult Create()
    {
        var db = new DB();
        IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(b => new SelectListItem { Value = b.basetype, Text = b.basetype });
        return View(new ViewModel { basetype=basetypes });
    }

Then, in your strongly typed view:

    <div class="editor-label">
        <%: Html.LabelFor(model => model.basetype) %>
    </div>
    <div class="editor-field">
        <%: Html.DropDownListFor(model=>model.basetype) %>
        <%: Html.ValidationMessageFor(model => model.basetype) %>
    </div>
Igor Zevaka
I've tried using the code in your "simple fix" example, and got the same error. I should have mentioned that the dropdown list populates in the View ok, but I get this error when I submit the form.
JBibbs
Can you post the code for the Controller Action that handles the form submission?
Igor Zevaka
Sure, I'll add it to the original post. Thanks for your help so far.
JBibbs
A: 

Try adding a string for the name of your dropdown list as the first parameter, and get the item out of your viewdata:

 <%= Html.DropDownList("SomeDropdownName", (IEnumerable<SelectListItem>)ViewData["basetype"]) %>

Here is also an extension method you can use so the dropdown list is set up in a similar style to how you have done your other controls:

        public static string DropDownList<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel)
        where TModel : class
    {
        string inputName = ExpressionHelper.GetInputName(expression);
        return htmlHelper.DropDownList(inputName, selectList, optionLabel);
    }

For example

<%= Html.DropDownList(x => x.BaseType, (IEnumerable<SelectListItem>)ViewData["basetype"], "")%>
CRice