I'm using ASP.NET MVC 3, and just ran into a 'gotcha' using the DropDownListFor
HTML Helper.
I do this in my Controller:
ViewBag.ShippingTypes = this.SelectListDataRepository.GetShippingTypes();
And the GetShippingTypes
method:
public SelectList GetShippingTypes()
{
List<ShippingTypeDto> shippingTypes = this._orderService.GetShippingTypes();
return new SelectList(shippingTypes, "Id", "Name");
}
The reason I put it in the ViewBag
and not in the model (I have strongly typed models for each view), is that I have a collection of items that renders using an EditorTemplate, which also needs to access the ShippingTypes select list.
Otherwise I need to loop through the entire collection, and assign a ShippingTypes property then.
So far so good.
In my view, I do this:
@Html.DropDownListFor(m => m.RequiredShippingTypeId, ViewBag.ShippingTypes as SelectList)
(RequiredShippingTypeId
is of type Int32
)
What happens is, that the value of RequiredShippingTypeId
is not selected in the drop down.
I came across this: http://web.archive.org/web/20090628135923/http://blog.benhartonline.com/post/2008/11/24/ASPNET-MVC-SelectList-selectedValue-Gotcha.aspx
He suggests that MVC will lookup the selected value from ViewData
, when the select list is from ViewData
. I'm not sure this is the case anymore, since the blog post is old and he's talking about MVC 1 beta.
A workaround that solves this issue is this:
@Html.DropDownListFor(m => m.RequiredShippingTypeId, new SelectList(ViewBag.ShippingTypes as IEnumerable<SelectListItem>, "Value", "Text", Model.RequiredShippingTypeId.ToString()))
I tried not to ToString
on RequiredShippingTypeId
at the end, which gives me the same behavior as before: No item selected.
I'm thinking this is a datatype issue. Ultimately, the HTML helper is comparing strings (in the Select List) with the Int32
(from the RequiredShippingTypeId
).
But why does it not work when putting the SelectList in the ViewBag
-- when it works perfectly when adding it to a model, and doing this inside the view:
@Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, Model.ShippingTypes)
See Question&Answers more detail:
os