我正在使用ASP.NET MVC 3,并且使用DropDownListForHTML Helper 遇到了"陷阱" .
我在我的控制器中执行此操作:
ViewBag.ShippingTypes = this.SelectListDataRepository.GetShippingTypes();
Run Code Online (Sandbox Code Playgroud)
和GetShippingTypes方法:
public SelectList GetShippingTypes()
{
List<ShippingTypeDto> shippingTypes = this._orderService.GetShippingTypes();
return new SelectList(shippingTypes, "Id", "Name");
}
Run Code Online (Sandbox Code Playgroud)
我把它放在ViewBag模型中而不是模型中的原因(我为每个视图都有强类型模型)是我有一组使用EditorTemplate渲染的项目,它还需要访问ShippingTypes选择列表.
否则我需要遍历整个集合,然后分配一个ShippingTypes属性.
到现在为止还挺好.
在我看来,我这样做:
@Html.DropDownListFor(m => m.RequiredShippingTypeId, ViewBag.ShippingTypes as SelectList)
Run Code Online (Sandbox Code Playgroud)
(RequiredShippingTypeId属于类型Int32)
什么情况是,该值RequiredShippingTypeId是不是在下拉选择向下.
我偶然发现了这个问题:http://web.archive.org/web/20090628135923/http : //blog.benhartonline.com/post/2008/11/24/ASPNET-MVC-SelectList-selectedValue-Gotcha.aspx
他建议ViewData当选择列表来自时,MVC将从中查找所选值ViewData.我不确定是不是这样了,因为博客文章已经过时了,他正在讨论MVC 1 beta.
解决此问题的解决方法是:
@Html.DropDownListFor(m => m.RequiredShippingTypeId, new SelectList(ViewBag.ShippingTypes as IEnumerable<SelectListItem>, "Value", "Text", Model.RequiredShippingTypeId.ToString()))
Run Code Online (Sandbox Code Playgroud)
我试着不要ToString在RequiredShippingTypeId没有选择的项目:在最后,这给了我同样的行为之前.
我认为这是一个数据类型问题.最终,HTML帮助程序将字符串(在"选择列表"中)与Int32(从中RequiredShippingTypeId)进行比较.
但是当将SelectList放入时,为什么它不起作用ViewBag- 当它在将模型添加到模型时完美地工作时,并在视图中执行此操作:
@Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, Model.ShippingTypes)
Run Code Online (Sandbox Code Playgroud)
Dar*_*rov 30
这不起作用的原因是由于DropDownListFor助手的限制:只有当这个lambda表达式是一个简单的属性访问表达式时,才能使用作为第一个参数传递的lambda表达式来推断所选值.例如,由于编辑器模板,这不适用于数组索引器访问表达式.
你基本上有(不包括编辑器模板):
@Html.DropDownListFor(
m => m.ShippingTypes[i].RequiredShippingTypeId,
ViewBag.ShippingTypes as IEnumerable<SelectListItem>
)
Run Code Online (Sandbox Code Playgroud)
不支持以下内容:m => m.ShippingTypes[i].RequiredShippingTypeId.它仅适用于简单的属性访问表达式,但不适用于索引集合访问.
您找到的解决方法是通过在构建时显式传递选定值来解决此问题的正确方法SelectList.