问题描述
我使用ASP.NET MVC 3,只是碰到了一个'疑难杂症'使用 DropDownListFor
HTML帮助。
我做这在我的控制器:
ViewBag.ShippingTypes = this.SelectListDataRepository.GetShippingTypes();
以及 GetShippingTypes
方法:
公开的SelectList GetShippingTypes()
{
清单< ShippingTypeDto> shippingTypes = this._orderService.GetShippingTypes(); 返回新的SelectList(shippingTypes,ID,姓名);
}
我把它的原因 ViewBag
,而不是在模型中(我强类型为每个视图模型),是我的项目的集合呈现使用EditorTemplate,这也需要访问ShippingTypes选择列表。
否则,我需要遍历整个集合,并分配一个ShippingTypes属性即可。
到目前为止好。
在我看来,我这样做:
@ Html.DropDownListFor(M = GT; m.RequiredShippingTypeId,ViewBag.ShippingTypes为的SelectList)
( RequiredShippingTypeId
的类型为的Int32
)
会发生什么情况是,中 RequiredShippingTypeId
值的不的在下拉菜单中选择。
我碰到这样的:http://web.archive.org/web/20090628135923/http://blog.benhartonline.com/post/2008/11/24/ASPNET-MVC-SelectList-selectedValue-Gotcha.aspx
他认为,MVC将查找从的ViewData 选定的值,当选择列表从
的ViewData 。我不知道这样的话了,因为博客文章是旧的,他在谈论MVC 1测试版。
这是解决这个问题的解决方法是这样的:
@ Html.DropDownListFor(M = GT; m.RequiredShippingTypeId,新的SelectList(ViewBag.ShippingTypes为IEnumerable< SelectListItem>中值,文本,Model.RequiredShippingTypeId.ToString ()))
我试着不去
的ToString
在 RequiredShippingTypeId
结尾,这给了我同样的行为之前:无项目中选择。
我想这是一个数据类型的问题。最终,HTML帮助是比较有字符串(在SELECT列表)的
的Int32
(从 RequiredShippingTypeId
)
但为什么它不把在选择列表时,工作
ViewBag
- 当将它添加到模型时,做此视图中完美的作品:
@ Html.DropDownListFor(M = GT; m.Product.RequiredShippingTypeId,Model.ShippingTypes)
解决方案
为什么这不工作的原因是因为 DropDownListFor
助手的限制:它是能够使用作为第一个参数传递拉姆达前pression推断所选值的仅在此拉姆达前pression是一个简单的属性访问前pression。例如,这不符合数组索引访问前pressions这是因为编辑器模板的工作你的情况。
您主要有(不包括编辑模板):
@ Html.DropDownListFor(
M => m.ShippingTypes [I] .RequiredShippingTypeId,
ViewBag.ShippingTypes为IEnumerable< SelectListItem>
)
以下是不受支持: M => m.ShippingTypes [I] .RequiredShippingTypeId
。它的工作原理只是简单的属性访问前pressions但不能与索引集合访问。
您已经找到了解决方法是解决这个问题,通过建立明确的时候传递所选值的正确方法的的SelectList
。
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)
解决方案 The reason why this doesn't work is because of a limitation of the DropDownListFor
helper: it is able to infer the selected value using the lambda expression passed as first argument only if this lambda expression is a simple property access expression. For example this doesn't work with array indexer access expressions which is your case because of the editor template.
You basically have (excluding the editor template):
@Html.DropDownListFor(
m => m.ShippingTypes[i].RequiredShippingTypeId,
ViewBag.ShippingTypes as IEnumerable<SelectListItem>
)
The following is not supported: m => m.ShippingTypes[i].RequiredShippingTypeId
. It works only with simple property access expressions but not with indexed collection access.
The workaround you have found is the correct way to solve this problem, by explicitly passing the selected value when building the SelectList
.
这篇关于ASP.NET MVC DropDownListFor不选择从模型值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!