ASP.NET MVC DropDownListNie wybiera wartości z modelu
Używam ASP.NET MVC 3 i po prostu wpadłem w 'gotcha' używającDropDownListFor
Pomocnik HTML.
Robię to w moim kontrolerze:
ViewBag.ShippingTypes = this.SelectListDataRepository.GetShippingTypes();
IGetShippingTypes
metoda:
public SelectList GetShippingTypes()
{
List<ShippingTypeDto> shippingTypes = this._orderService.GetShippingTypes();
return new SelectList(shippingTypes, "Id", "Name");
}
Powód, dla którego umieściłem go wViewBag
a nie w modelu (mam silnie wpisane modele dla każdego widoku), mam to, że mam kolekcję elementów, które renderują za pomocą EditorTemplate, która również musi uzyskać dostęp do listy wyboru ShippingTypes.
W przeciwnym razie muszę zapętlić całą kolekcję i przypisać następnie właściwość ShippingTypes.
Jak na razie dobrze.
Moim zdaniem robię to:
@Html.DropDownListFor(m => m.RequiredShippingTypeId, ViewBag.ShippingTypes as SelectList)
(RequiredShippingTypeId
jest typuInt32
)
Co się dzieje, że wartośćRequiredShippingTypeId
jestnie wybrane na liście rozwijanej.
Natknąłem się na to:http://web.archive.org/web/20090628135923/http://blog.benhartonline.com/post/2008/11/24/ASPNET-MVC-SelectList-selectedValue-Gotcha.aspx
Sugeruje, że MVC wyszuka wybraną wartość zViewData
, kiedy lista wyboru jest zViewData
. Nie jestem pewien, czy to już tak jest, ponieważ post na blogu jest stary i mówi o beta MVC 1.
Rozwiązaniem tego problemu jest:
@Html.DropDownListFor(m => m.RequiredShippingTypeId, new SelectList(ViewBag.ShippingTypes as IEnumerable<SelectListItem>, "Value", "Text", Model.RequiredShippingTypeId.ToString()))
Starałem się tego nie robićToString
naRequiredShippingTypeId
na końcu, co daje mi takie samo zachowanie jak wcześniej: Nie wybrano żadnego elementu.
Myślę, że jest to problem typu danych. Ostatecznie, pomocnik HTML porównuje ciągi (na liście wyboru) z ciągiemInt32
(odRequiredShippingTypeId
).
Ale dlaczego to nie działa, gdy umieszczasz SelectList wViewBag
- gdy działa idealnie po dodaniu go do modelu i robi to wewnątrz widoku:
@Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, Model.ShippingTypes)