Reputation: 31
In my controller I have:
Category x = new Category(1, "one", 0);
Category y = new Category(2, "two", 1);
Category z = new Category(3, "three", 1);
List<Category> categories = new List<Category>();
categories.Add(x);
categories.Add(y);
categories.Add(z);
ViewData["categories"] = categories;
And in my view I have:
<%= Html.DropDownList("categories")%>
But I have an error:
The ViewData item that has the key 'categories' is of type 'System.Collections.Generic.List`1[[Category, MvcApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' but must be of type 'IEnumerable'.
Uggggghhh how to resolve this?
Upvotes: 1
Views: 5203
Reputation: 26018
The better way to do this is to create a view model for each view/page, populate it with data (if required) and return this to the view/page. Never return your domain model to the view/page.
The code provided below is for ASP.NET MVC3, but it is easy to relate to your situation
Lets assume you are creating a new product which needs to be in a category (displayed in a select list), so you will need a Create view/page and action method. I would create the following view model:
public class ProductCreateViewModel
{
// Include other properties if needed, these are just for demo purposes
public string Name { get; set; }
public string SKU { get; set; }
public string LongDescription { get; set; }
// This is the unique identifier of your category,
// i.e. foreign key in your product table
public int CategoryId { get; set; }
// This is a list of all your categories populated from your category table
public IEnumerable<Category> Categories { get; set; }
}
Category class:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
In your Create view you would have the following:
@model MyProject.ViewModels.ProductCreateViewModel
@using (Html.BeginForm())
{
<table>
<tr>
<td><b>Category:</b></td>
<td>
@Html.DropDownListFor(x => x.CategoryId,
new SelectList(Model.Categories, "Id", "Name", Model.CategoryId),
"-- Select --"
)
@Html.ValidationMessageFor(x => x.CategoryId)
</td>
</tr>
</table>
<!-- Add other HTML controls if required and your submit button -->
}
Your Create action methods:
public ActionResult Create()
{
ProductCreateViewModel viewModel = new ProductCreateViewModel
{
// Here you do a database call to populate your dropdown
Categories = categoryService.GetAllCategories()
};
return View(viewModel);
}
Upvotes: 0
Reputation: 64
I know this is old but in case someone is looking for the answer
supposing that Categories have and Id, and Name and the current CategoryId is in the model
@Html.DropDownListFor(m => m.CategoryId, new SelectList((IEnumerable)ViewData["categories"], "Id", "Name"))
Upvotes: 0
Reputation: 2905
Use Jquery Ajax + JSON is to fill the dropdown. This will result in better responsive web page.
It is so simple. All you have to do is, add a new action of returntype JSONResult and moves the dropdown loading codes to there.
In Controller Class:
Create a new action:
public JsonResult FillDropDown()
{
Category x = new Category(1, "one", 0);
Category y = new Category(2, "two", 1);
Category z = new Category(3, "three", 1);
List<Category> categories = new List<Category>();
categories.Add(x);
categories.Add(y);
categories.Add(z);
return Json(categories,JsonRequestBehavior.AllowGet);
}
In View Page: Add Jquery code for load data from server.
<script type="text/javascript">
$(document).ready(function ()
{
var _selbxTest = $('#selbxTest'); //Get dropdownlistbox
$.getJSON(
'@Url.Action("FillDropDown","Home")', //Provide JsonResultActionName, ControllerName
{},
function (_recdData) {
//Update dropdownListBox here
_selbxTest.append($('<option></option>').val(0).html('Select'));
$.each(_recdData, function (key, value) {
_selbxTest.append($('<option></option>').val(value.value).html(value.text));
});
});
});
</script>
Finally add a simple selectbox in your view page instead of Html.DropDownList()
<div>
<select id="selbxTest"></select>
</div>
Hope this will help you. Thanks.
Upvotes: 0
Reputation: 60493
You can maybe try
ViewData["categories"] = new SelectList(categories, "Id", "Name");
(assuming Category has a Name and and Id Field)
Then you can add logic to keed selected value.
EDIT : cause your error message is not complete, if I'm not wrong : it's asking for an IEnumerable<SelectListItem>
Upvotes: 3
Reputation: 32831
In the line before you create the ViewData
item, you can convert the List<T>
to an IEnumerable<T>
IEnumerable<Category> cat = categories;
ViewData["categories"] = cat;
Upvotes: 0