开发者

DropDownListFor and relating my lambda to my ViewModel

After googling for a while I'm still drawing a blank here. I'm trying to use a ViewModel to pull and provide a dictionary to a dr开发者_C百科op down list inside a strongly typed View:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="EveNotebook.ViewModels.CorporationJoinViewModel" %>

...

<%: Html.DropDownListFor(c => c.CorpDictionary.Keys, new SelectList(Model.CorpDictionary, "Value", "Key"))%>

I'm getting the error:

CS1061: 'object' does not contain a definition for 'CorpDictionary' and no extension method 'CorpDictionary' accepting a first argument of type 'object' could be found

and the relevant bit of my ViewModel

   public class CorporationJoinViewModel
    {
        DB _eveNotebook = new eveNotebookDB(); // data context

        public Dictionary<int, string> CorpDictionary
        {
            get
            {
                Dictionary<int, string> corporations = new Dictionary<int, string>();

                int x = 0;
                foreach (Corporation corp in _db.Corporations)
                {
                    corporations.Add(x, corp.name);
                }

                return corporations;
            }
        }

I'll admit I have a pretty magical understanding of how linq is finding my ViewModel object from that lambda, and the error message is making me think it's not. Is my problem the method I'm using to pass the data? What am I missing here?


Solution

(Very similar to the excellent answer but ran through the compiler and fixed a few typos in the process):

Controller

  var model = new CorporationJoinViewModel
                {
                    Corps = _eveNotebook.Corporations.Select( c => new SelectListItem
                                     {
                                          Text = c.name,
                                          Value = c.id.ToString()
                                     })
                };
    
    return View(model);

View

Inherits="System.Web.Mvc.ViewPage<IEnumerable<EveNotebookLibrary.Models.Corporation>>" %>

...

<%: Html.DropDownListFor(c => c.Corps, new SelectList(Model.Corps))%>

ViewModel

public class CorporationJoinViewModel : ViewPage
{
    public int CorporationId { get; set; }

    public IEnumerable<SelectListItem> Corps { get; set; }
}


First, you're not using link, you're simply using a lambda expression to specify the property on the model. Second, your view needs to inherit from ViewPage, in this case, a strongly-typed view page specific to your model. Third, I'd suggest that you have a property for the CorporationId (to post back from the value of the select) and an IEnumerable<SelectListItem> to supply values for the dropdown rather than using magic strings to construct a SelectList. This could use LINQ, or extension methods, to do the selection.

Normally, I wouldn't have the view model be anything other than a container -- it should be database agnostic. Fill the view model in your controller from the DB.

<%@ Page Title="" Language="C#"
    MasterPageFile="~/Views/Shared/Site.Master"
    Inherits="System.Web.Mvc.ViewPage<EveNotebook.ViewModels.CorporationJoinViewModel>"
 %>

<%: Html.DropDownListFor(c => c.CorporationId, Model.CorpDictionary )%>

Model code

public class CorporationJoinViewModel
{
    public int CorporationId { get; set; }

    public IEnumerable<SelectListItem> CorpDictionary { get; set; }
}

Controller code

...
var model = new CorporationJoinViewModel
            {
                CorpDictionary = _eveNotebook.Corporations.Select( c => new SelectListItem
                                 {
                                      Text = c.name,
                                      value = c.id.ToString()
                                 }
            };
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜