将数据绑定到MVC中的下拉列表的问题

时间:2010-10-22 23:38:49

标签: c# asp.net-mvc binding drop-down-menu

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

2 个答案:

答案 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)%>