Problems binding data to dropdownlist in MVC
Learning MVC and having major trouble over the last two days trying to bind data from a database to a dropdownlist in MVC. I'm currently following the nerddinner tutorial. I have followed it exactly and somehow still ended up with this error.
The ViewData item that has the key 'Dinner.Country' is of type 'System.String' but must be of type 'IEnumerable'.
I understand this is a lot of code to look at but if anyone feels so inclined to have a look over it - I'd be very grateful.
Here is my code:
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));
}
And here is the snippet from the View that is causing me problems - Edit.aspx
<div class="editor-field">
<%: Html.DropDownListFor(m => m.Dinner.Country, ViewData["countries"] as SelectList)%>
<%: Html.ValidationMessageFor(m => m.Dinner.Country, "*")%>
</div>
Also, I have bits of code commented out, these are from earlier in the tutorial and can be ignored. Also, for anyone who can actually understand what the stack trace, here it is:
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\N开发者_运维技巧erdDinner\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
First you need to define a property which will hold the selected country id on your view model:
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);
}
}
And then:
<%: Html.DropDownListFor(m => m.SelectedCountry, Model.Countries) %>
Change this:
<%: Html.DropDownListFor(m => m.Dinner.Country, ViewData["countries"] as SelectList)%>
to:
<%: Html.DropDownListFor(m => m.Dinner.Country, Model.Countries.Items)%>
精彩评论