Reputation: 927
I have a little problem in populating a drop down list in MVC3. I hope there would be somebody to give me a help on this.
I am trying to render a View of Users which contains a DropDownList for Cities. This should be fetched from the Database. In fact, The User class has a ForeignKey of the City class.
Here are the Controller and the View:
public ViewResult Index()
{
//return View(model);
var DefaultCities = new[]
{
new {Name = "London"}
}.ToList();
IEnumerable<SelectListItem> cities = unitOfWork.CityRepository.Get() as IEnumerable<SelectListItem>;
ViewData["AllCities"] = cities != null ? new SelectList(cities.AsEnumerable(), "CityID", "Name") : new SelectList(DefaultCities.AsEnumerable(), "Name");
return View(unitOfWork.UserRepository.Get(orderBy: us => us.OrderByDescending(u => u.ID)).OfType<User>().ToList());
}
//The View
<div class="editor-field">
@Html.DropDownList(**"CityID"**, ViewData["AllCities"] as SelectList, "--Choose One--"))
@Html.ValidationMessageFor(model => model.CityID)
</div>
But the following error displays:
There is no ViewData item of type 'IEnumerable' that has the key 'CityID'.
This is my first time on MVC! What does the 'CityID' refer to? What should I write as the first argument of @Html.DropDownList
?
As I have read on different articles, the argument mentioned should be the name of the form field.
Can anyone suggest a sample code? Any help would be appreciated.
Upvotes: 1
Views: 482
Reputation: 6467
Well, looking at your code, if the cities are null then it goes to your Default Cities. However, you've only listed a Name and not a CityID in the default SelectList.
You may also want to just try to bind the default collection first to make sure it works. Then try the other... just some debugging tips to narrow it down.
Here's what you need:
var cities = unitOfWork.CityRepository.Get();
ViewData["AllCities"] = cities != null ? new SelectList(cities, "CityID", "Name") : new SelectList(DefaultCities.AsEnumerable(), "CityID", "Name");
And you view would be:
@Html.DropDownList("Cities",(SelectList)ViewData["AllCities"])
Also, I just saw where you are defining DefaultCities. It doesn't have a CityID either. This:
var DefaultCities = new[]
{
new {Name = "London"}
}.ToList();
Should be this:
var DefaultCities = new[]
{
new {Name = "London", CityID=1}
}.ToList();
Upvotes: 1
Reputation: 1039438
The following line of code is wrong:
new SelectList(cities.AsEnumerable(), "CityID", "Name")
You are specifying CityID
and Name
properties but cities
is an IEnumerable<SelectListItem>
. And SelectListItem
only has Value
and Text
properties. There's no such thing as CityID
and Name
.
So you probably meant:
ViewData["AllCities"] = cities != null
? new SelectList(cities, "Value", "Text")
: new SelectList(DefaultCities, "Name");
or simply:
ViewData["AllCities"] = cities != null
? cities
: new SelectList(DefaultCities, "Name");
and in your view:
@Html.DropDownList(
"CityID",
ViewData["AllCities"] as IEnumerable<SelectListItem>,
"--Choose One--"
)
As far as the CityID
argument in your view is concerned, this will basically be used by the DropDownList helper to generate the name
property of the select element in your DOM and as a consequence that will be the selected value name being passed to the controller action that you are submitting your form to.
By the way using ViewData/ViewBag is very bad practice. I would recommend you using a view model instead and have a strongly typed DropDownListFor helper in your view which will be tied to a specific property on your view model.
Upvotes: 5
Reputation: 6294
Im curious how the output of your cities repository casts to IEnumerable<SelectListItem>
But assuming its a enumeration of city objects you can try the following
In your controller
ViewBag.Cities = new SelectList(unitOfWork.CityRepository.Get(), "CityID", "Name");
In your view
<div class="editor-field">
@Html.DropDownList("CityID", (SelectList)ViewBag.Cities)
</div>
Upvotes: 1