学习MVC并在过去两天遇到重大麻烦,试图将数据从数据库绑定到MVC中的下拉列表。我正在关注nerddinner教程。我跟着它完全并且不知何故仍然以此错误结束。
具有键的ViewData项 'Dinner.Country'属于类型 'System.String'但必须是类型 '的IEnumerable'。
我知道这是很多要看的代码,但是如果有人感觉如此倾向于看一眼 - 我会非常感激。
这是我的代码:
DinnerFormViewModel.cs
public class DinnerFormViewModel
{
private static string[] _countries = new[] {
"USA",
"UK",
"IRL",
"SA"
};
//Properties
public Dinner Dinner { get; private set; }
public SelectList Countries { get; private set; }
//Constructor
public DinnerFormViewModel(Dinner dinner)
{
Dinner = dinner;
Countries = new SelectList(_countries, dinner.Country);
}
DinnersController.cs
//
//GET: /Dinners/Edit/2
//[Authorize]
public ActionResult Edit(int id)
{
Dinner dinner = dinnerrepository.GetDinner(id);
//var countries = new[] {
// "USA", "Afganistan", "UK", "Ireland"};
//ViewData["countries"] = new SelectList(countries, dinner.Country);
return View(new DinnerFormViewModel(dinner));
}
//
//POST: /Dinners/Edit/2
[HttpPost]
public ActionResult Edit(int id, FormCollection formvalues)
{
//Retrieve Existing Dinner
Dinner dinner = dinnerrepository.GetDinner(id);
//Update dinner with form posted values
//dinner.Title = Request.Form["Title"];
//dinner.Description = Request.Form["Description"];
//dinner.EventDate = DateTime.Parse(Request.Form["EventDate"]);
//dinner.Address = Request.Form["Address"];
//dinner.Country = Request.Form["Country"];
//dinner.ContactPhone = Request.Form["ContactPhone"];
if (TryUpdateModel(dinner))
{
//Persist changes back to database
dinnerrepository.Save();
//Perform HTTP redirect to details page for the saved dinner
return RedirectToAction("Details", new { id = dinner.DinnerID });
}
//var countries = new[] {
// "USA", "Afganistan", "UK", "Ireland"};
//ViewData["countries"] = new SelectList(countries, dinner.Country);
return View(new DinnerFormViewModel(dinner));
}
以下是View中引起我问题的片段 - Edit.aspx
<div class="editor-field">
<%: Html.DropDownListFor(m => m.Dinner.Country, ViewData["countries"] as SelectList)%>
<%: Html.ValidationMessageFor(m => m.Dinner.Country, "*")%>
</div>
此外,我已经注释掉了一些代码,这些代码来自本教程的前面部分,可以忽略。此外,对于任何能够真正了解堆栈跟踪的人来说,这里是:
InvalidOperationException: The ViewData item that has the key 'Dinner.Country' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>'.]
System.Web.Mvc.Html.SelectExtensions.GetSelectData(HtmlHelper htmlHelper, String name) +458
System.Web.Mvc.Html.SelectExtensions.SelectInternal(HtmlHelper htmlHelper, String optionLabel, String name, IEnumerable`1 selectList, Boolean allowMultiple, IDictionary`2 htmlAttributes) +321
System.Web.Mvc.Html.SelectExtensions.DropDownListHelper(HtmlHelper htmlHelper, String expression, IEnumerable`1 selectList, String optionLabel, IDictionary`2 htmlAttributes) +48
System.Web.Mvc.Html.SelectExtensions.DropDownListFor(HtmlHelper`1 htmlHelper, Expression`1 expression, IEnumerable`1 selectList, String optionLabel, IDictionary`2 htmlAttributes) +115
System.Web.Mvc.Html.SelectExtensions.DropDownListFor(HtmlHelper`1 htmlHelper, Expression`1 expression, IEnumerable`1 selectList) +87
ASP.views_dinners_edit_aspx.__RenderContent2(HtmlTextWriter __w, Control parameterContainer) in c:\Users\TaraW\Documents\Visual Studio 2010\Projects\NerdDinner\NerdDinner\Views\Dinners\Edit.aspx:52
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Control.Render(HtmlTextWriter writer) +10
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\Users\TaraW\Documents\Visual Studio 2010\Projects\NerdDinner\NerdDinner\Views\Shared\Site.Master:26
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Control.Render(HtmlTextWriter writer) +10
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Page.Render(HtmlTextWriter writer) +29
System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +56
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060
答案 0 :(得分:3)
首先,您需要定义一个属性,该属性将在您的视图模型中保存所选的国家/地区ID:
public class DinnerFormViewModel
{
private static string[] _countries = new[] {
"USA",
"UK",
"IRL",
"SA"
};
//Properties
public Dinner Dinner { get; private set; }
// will hold the selected country value
public string SelectedCountry { get; set; }
public SelectList Countries { get; private set; }
//Constructor
public DinnerFormViewModel(Dinner dinner)
{
Dinner = dinner;
Countries = new SelectList(_countries, dinner.Country);
}
}
然后:
<%: Html.DropDownListFor(m => m.SelectedCountry, Model.Countries) %>
答案 1 :(得分:0)
改变这个:
<%: Html.DropDownListFor(m => m.Dinner.Country, ViewData["countries"] as SelectList)%>
为:
<%: Html.DropDownListFor(m => m.Dinner.Country, Model.Countries.Items)%>