Search code examples
asp.net-mvchtml-helper

Loading model to HTML DropDownListFor helper


I have a simple Model called Region which is like

namespace App
{
    using System;
    using System.Collections.Generic;

    public partial class Region
    {
        public int RegionID { get; set; }
        public string RegionDescription { get; set; }
    }
}

and I am trying to load the model into a HTML DropDownListFor() helper in view like

@model IEnumerable<App.Region>

<div class="row">
    @Html.DropDownListFor("RegionList",
                    new SelectList(model => model.RegionDescription),
                    "Select Region",
                    new { @class = "form-control" })

</div>

or

@model IEnumerable<App.Region>
<div class="row">
    @Html.DropDownListFor("RegionList",
                        new SelectList(s => s.RegionDescription),
                        "Select Region",
                        new { @class = "form-control" })

</div>

or:

@model IEnumerable<App.Region>
<div class="row">
@foreach (var item in Model)
{
    @Html.DropDownListFor("RegionList",
                        new SelectList(model => item.RegionDescription),
                        "Select Region",
                        new { @class = "form-control" })
}
</div>

but in both ways I am getting this error.

Cannot convert lambda expression to type 'object' because it is not a delegate type

Why is this happening and how I can fix it?


Solution

  • SelectList constructor takes a collection as the first argument. not a lamda expression ! You are using the helper method in an incorrect way!

    Ideally, Html.DropDownListFor method's first parameter is an expression from which the helper will be able to get the value of the view model property. That means, to use it, your view model should have a property to store the selected option value. So create a view model like this

    public class CreateVm
    {
      public int SelectedRegion { set;get;}
      public List<SelectListItem> Regions { set;get;}
    }
    

    Now in your GET action, you need to create an object of this view model, load the Regions collection property and send that to the view

    public ActionResult Create()
    {
      var vm = new CreateVm();
      vm.Regions = new List<SelectListItem>{
             new SelectListItem { Value="1", Text="Region1"},
             new SelectListItem { Value="2", Text="Region2"},
             new SelectListItem { Value="3", Text="Region3"}
      };
      return View(vm);
    }
    

    and in your view which is strongly typed to this new view model, you can use the DropDownListFor helper method like this

    @model CreateVm
    @Html.DropDownListFor(x=>x.SelectedRegion,Model.Regions,"Select Region",
                                                                new { @class = "form-control" })
    

    Or if you do want to use your existing view model/type passed to the view, you may consider using the Html.DropDownList helper method to render a SELECT element

    @Html.DropDownList("SelectedRegion", 
                        new SelectList(Model, "RegionID", "RegionDescription"), "Select Region",
                        new { @class = "form-control" })
    

    This will render a SELECT element with the name "SelectedRegion"