键为“ MY KEY”的 ViewData 项的类型为“ System. String”,但必须为“ IEnumable < SelectListItem >”类型

我正在尝试使用 ASP.NET MVC 2从使用 Linq-2-SQL 映射的数据库中填充一个下拉列表,并继续得到这个错误。

我感到非常困惑,因为我在第二行声明了一个类型为 IEnumerable<SelectListItem>的变量,但是这个错误让我认为情况并非如此。我觉得这应该很简单,但我很挣扎。感谢你的帮助。

下面是我的控制器中有趣的部分:

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();
}

以下是我的一些有趣的观点:

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

下面是提交表单时的 POST 操作

// 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);
}
}

谢谢。

101455 次浏览

您正在将集合设置为 ViewData 字典中的项,并尝试将其作为模型上的属性检索。一个简单的修复方法是按照设置它的方式引用它:

    <%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>

或者,下面的代码使用强类型视图:

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 });
}

那么,在你的强类型观点中:

    <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>

尝试为下拉列表的名称添加一个字符串作为第一个参数,并从视图数据中取出该项:

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

这里还有一个扩展方法,你可以使用它来设置下拉列表,其风格与你设置其他控件的风格相似:

        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);
}

比如说

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

我刚刚遇到这个问题,这篇文章帮助我通过它-http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx

最有可能的原因是您的集合在 po 之后被重新填充

我也遇到了同样的问题,最终我得到了答案。

问题在于,在 POST 操作中,在提交表单之后,ModelState 无效,或者它在 try/catch 中捕获错误,因此返回 View。但是这次视图没有正确设置 ViewData["basetype"]

您需要再次填充它,可能需要使用以前使用的相同代码,因此请重复以下操作:

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

[HttpPost]方法的 return View(meal)之前。

这样就能解决你的问题了:

[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);
}
}

我知道这个问题很老了,但是我今天来这里也有同样的问题,所以其他人可以晚点再来..。

如果您使用 Html.DropDownList()方法-如果您的 ViewData/Viewbag 项没有设置,可能会发生同样的错误,如@Peto 所回答的。

但是在控制器集项的情况下可能无法正确设置,但是在主视图中使用带有新 ViewDataDictionary 值的部分视图调用。

如果您有 @Html.Partial("Partianame", Model,new ViewDataDictionary() { /* ... */ }),那么您的部分视图将看不到 ViewDataViewBag数据,删除 new ViewDataDictionary()参数

如果 SelectList 为 null,您将收到此错误。

对于未来的读者,

我今天碰到了这个问题,但是无法解决。事情终于变得简单了。我使用的是表 + 视图。当我更新表(添加了一些列)时,我忘记更新(删除并重新创建)视图,这给我带来了问题。 希望能帮到别人。

对于未来的读者,如果您正在使用剃须刀,请尝试将选择列表项的类型从 List 更改为 IEnumable。

@Html.DropDownListFor(m => m.id, ViewBag.SomeList as List<SelectListItem>)

@Html.DropDownListFor(m => m.id, ViewBag.SomeList as IEnumerable<SelectListItem>)

我今天得到了同样的错误,我的解决方案是使模型“有效”。

在我的例子中,在用户通过单击“ save”提交之后,我得到了模型状态: 如果用户键入“0”则无效,但是如果用户键入“0.0”则模型状态将有效。

所以我重写了“ IsValid”方法,即使用户键入“0”也返回 true。

希望能有帮助。