Search code examples
asp.net-mvchtml-helperselectlistitem

List<SelectListItem>() for html helper DropDownListFor()


I am trying to generate a list as follows-

@using SkyTracker.Models
@model SkyTracker.Models.Outlet
@{
    var outletTypeList = new List<SelectListItem>();
    foreach (var item in ViewBag.OutletTypes)
    {
        //Exception Cannot implicitly convert type 'int' to 'string'
        var newType = new SelectListItem { Text = item.OutletTypeName, Value = item.OutletTypeId };
        outletTypeList.Add(newType);
    }
}



<form method="post" action="@(ViewBag.BaseUrl)OutletManagement/Create?id=@ViewBag.RaId">
    @Html.LabelFor(m => m.OutletTypeId, new { @class="required"})
    @Html.DropDownListFor(m => m.OutletTypeId, outletTypeList, new {required="required" })

</form>

But I'm gettting an exception in the foreach loop. Any help?


Solution

  • The Value property of SelectListItem is tyeof string so if OutletTypeId is typeof int, then use Value = item.OutletTypeId.ToString().

    However that code belongs in the controller, not the view, and ideally you should be using a view model that contains a property IEnumerable<SelectListItem> OutletTypeList

    public class OutletVM
    {
        [Required(ErrorMessage = "Please select an outlet type")]
        public int? OutletTypeId { get; set; } // nullable to protect against under-posting attacks
        public IEnumerable<SelectListItem> OutletTypeList { get; set; }
        ....
    }
    

    and in the controller

    OutletVM model = new OutletVM()
    {
        OutletTypeList = yourCollection.Select(x => new SelectListItem
        {
            Value = x.OutletTypeId.ToString(),
            Text = x.OutletTypeName
        },
        .... // set other properties of the view model
    };
    return View(model);
    

    and in the view

    @Html.DropDownListFor(m => m.OutletTypeId, Model.OutletTypeList, "Please select")
    @Html.ValidationMessageFor(m => m.OutletTypeId)
    

    Note also that you should remove new {required="required" } which is HTML5 client side validation only and add a RequiredAttribute to the property your binding to so that you get both client and server side validation.

    Consider also using

     @using (Html.BeginForm("Create", "OutletManagement", new { id = @ViewBag.RaId }))
    

    to generate the form element