The ViewData item that has the key 'MY KEY' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>'
asp.net Mvcasp.net Mvc Problem Overview
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 of 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.
asp.net Mvc Solutions
Solution 1 - asp.net Mvc
I had same problem, and finally I got the answer...
The problem is that in the POST action, after submitting the form, the ModelState is not valid, or it's catching an error in try/catch, so the View is returned. But this time the View has not the ViewData["basetype"]
correctly set.
You need to populate it again, probably with the same code used before, so repeat this:
var db = new DB();
IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
b => new SelectListItem { Value = b.basetype, Text = b.basetype });
ViewData["basetype"] = basetypes;
before the return View(meal)
in the [HttpPost]
method.
exactly this will solve your problem:
[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
{
var db = new DB();
IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
b => new SelectListItem { Value = b.basetype, Text = b.basetype });
ViewData["basetype"] = basetypes;
return View(meal);
}
}
else
{
var db = new DB();
IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
b => new SelectListItem { Value = b.basetype, Text = b.basetype });
ViewData["basetype"] = basetypes;
return View(meal);
}
}
I know this question is very old, but I came here today with the same problem, so other could come here later...
Solution 2 - asp.net Mvc
You will receive this error if the SelectList is null.
Solution 3 - asp.net Mvc
I've just come across this issue and this article helped me through it - http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx
The most likely cause it that your collection is repopulated after the po
Solution 4 - asp.net Mvc
For future readers, if you are using razor, try to change type of selectlist item from List to IEnumerable.
From
@Html.DropDownListFor(m => m.id, ViewBag.SomeList as List<SelectListItem>)
To
@Html.DropDownListFor(m => m.id, ViewBag.SomeList as IEnumerable<SelectListItem>)
Solution 5 - asp.net Mvc
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>
Solution 6 - asp.net Mvc
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"], "")%>
Solution 7 - asp.net Mvc
If you use Html.DropDownList()
method - same error may occur, if your ViewData/Viewbag item not set, as @Peto answered.
But it may be not set in case of controller set item correctly, but in main view you use partial viw call with new ViewDataDictionary values.
if you have @Html.Partial("Partianame", Model,new ViewDataDictionary() { /* ... */ })
then your partial view will not see ViewData
and ViewBag
data, remove new ViewDataDictionary()
parameter
Solution 8 - asp.net Mvc
To future readers,
I came across with the problem today and couldnĀ“t fix it. It turned to be really simple after all. I was working with a table + view. When I updated the table (added a few colums) I forgot to update (drop and recreate) the view, which caused the problem for me. Hope it helps somebody.
Solution 9 - asp.net Mvc
I got same error today and my solution is to make model "valid".
In my case, after user submit by clicking "save", I got model state: invalid if user key-in "0", but model state will be valid if user key-in "0.0".
So I override "IsValid" method to return true even user key-in "0".
Hope it helps.