Reputation: 5002
This is how I populate dropdownlist and create html element;
AccountController:
public ActionResult Index()
{
ViewBag.Towns = new SelectList(_skrsService.GetTowns(), "Value", "Text", 1);
return View();
}
...
public List<SelectListItem> GetTowns()
{
var list = UnitOfWork.Repository<SkrsIl>().OrderBy(x => x.Adi).Select(x => new SelectListItem()
{
Text = x.Adi,
Value = x.Kodu.ToString()
}).ToList();
return list;
}
Login.cshtml(Hometown is string field in model bindned to login view page):
@Html.DropDownListFor( x => x.Hometown, ((SelectList)ViewBag.Towns), new { @class = "form-control", placeholder = "Doğum Yeri" })
I expected this to work but getting error, message:
"The ViewData item that has the key 'Hometown' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>'."
how can I make it work properly? I just expected selectem item value to 'Hometown' property
Upvotes: 1
Views: 1772
Reputation:
The error means that that ViewBag.Towns
is null
. When the 2nd parameter (IEnumerable<SelectListItem> selectList
) is null
, the method expects the first parameter to be typeof IEnumerable<SelectListItem>
.
Since you have assigned it in the GET method, this is almost certainly happening when you submit your form and have returned the view but have not repopulated the value of ViewBag.Towns
as you did in the GET method.
As a side note, using new SelectList()
is pointless extra overhead - it just creates another IEnumerable<SelectListItem>
based on the first one. In addition, the 4th parameter of the SelectList
constructor is ignored when you bind to a model property - internally the method builds a new IEnumerable<SelectListItem>
and sets the Selected
property based on the value of the property your binding to.
Your controller code should be
public ActionResult Index()
{
ViewBag.Towns = _skrsService.GetTowns();
return View(); // ideally you should be returning a model
}
[HttpPost]
public ActionResult Index(YourModel model)
{
if (!ModelState.IsValid)
{
ViewBag.Towns = _skrsService.GetTowns(); // re-populate the SelectList
return View(model);
}
// save and redirect
}
But preferably you should be using a view model containing a property for the select list rather than ViewBag
.
Upvotes: 1