2010-08-03 56 views
131

我试图从映射Linq-2的数据库中填充下拉列表, SQL,使用ASP.NET MVC 2,并不断收到此错误。具有'MY KEY'键的ViewData项的类型为'System.String',但必须是'IEnumerable <SelectListItem>'的类型

我很困惑,因为我在第二行宣布了一个类型为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); 
    } 
} 

谢谢。

+0

奇怪,看起来对我来说还行:/ – 2010-08-03 04:13:17

+0

下拉列表出现在视图中就好了。它从数据库中填充,因为它应该,但是当我发布表单时,我得到这些错误。 – JBibbs 2010-08-04 02:08:34

+5

已接受答案摘要:确保在控制器的get和post操作中填充列表。忘记做这件事很容易,然后浪费时间寻找更复杂的错误。 – 2015-05-07 13:39:06

回答

196

我有同样的问题,最后我得到了答案......

的问题是,在POST操作,提交表单后,ModelState中是无效的,或者它赶上一个错误的try /赶上,所以视图返回。但是这次查看并没有正确设置ViewData["basetype"]

您需要再次填充它,可能与之前使用的相同的代码,如此重复这样的:在[HttpPost]方法return View(meal)

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

正是这将解决你的问题:

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

我知道这个问题是很老了,但我今天来到这里,同样的问题,因此其他可能来这里后......

+7

+1为“再次填充它”...我有一个相当强大的系统来组成我的视图模型,但我完全忘记了称之为。因此,该财产没有填充,我收到这个(相当模糊)的消息,不管我尝试了什么。 – 2012-12-25 06:05:18

+8

如果你之前得到这个帖子,那是因为SelectList中没有任何东西,只是找到了一个。 – Martin 2013-04-14 11:16:38

+1

+1因为当我真的调用另一个Action Method的Html.Action时,我在Index方法中设置ViewBag! – SwampyFox 2013-05-31 12:30:06

0

您正在将集合设置为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> 
+0

我试过在你的“简单修复”例子中使用代码,并得到了同样的错误。我应该提到下拉列表填充在视图确定,但我提交表单时出现此错误。 – JBibbs 2010-08-04 02:42:22

+0

你可以发布处理表单提交的Controller Action的代码吗? – 2010-08-04 02:43:48

+0

当然,我会将其添加到原始帖子。感谢您一直以来的帮助。 – JBibbs 2010-08-04 05:23:26

0

尝试添加字符串为您的下拉列表中的第一个参数的名称,并获得该项目出你的可视数据的:

<%= 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"], "")%> 
0

如果您使用Html.DropDownList()方法 - 如果您的ViewData/Viewbag项目未设置,则可能会发生同样的错误,因为@Peto已回答。

但是,在控制器正确设置项目的情况下,它可能不会被设置,但在主视图中,您可以使用新的ViewDataDictionary值使用部分viw调用。

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

80

如果选择列表的是无效,您将收到此错误。

+13

呃,那么简单,但误导性的错误信息。 – 2015-04-06 02:49:48

+3

是的,这是一个常见的错误/疏忽,当你设置一个GET的SelectList然后回发到POST动作(显然)有一个'ModelState.IsValid == false',所以你返回模型'返回视图(模型) '但是在从POST返回之前不要重新填充您的SelectList源代码。由于没有ViewState ala WebForms,所以'@ Html.DropDown'帮助程序没有资源来重建select。您必须在每次将视图返回给客户端时填充该源列表,而不仅仅是GET。 – rism 2015-05-13 01:19:26

+0

是的,这是我的问题。忘记在get call上填充selectList。非常误导性的错误。好帖子。 – Matt 2015-11-15 19:22:27

0

给未来的读者,

我今天遇到了这个问题,无法修复它。毕竟它变得非常简单。我正在使用表格+视图。当我更新了表格(添加了几个colums)后,我忘记了更新(删除并重新创建)视图,这导致了我的问题。 希望它有助于某人。

相关问题