2010-08-03 54 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)後,我忘記了更新(刪除並重新創建)視圖,這導致了我的問題。 希望它有助於某人。

相關問題