[英]DropDownListFor not selecting the selected item in the SelectList
I am working on an ASP.NET MVC3 application and I cannot get a DropDownListFor to work with my property in a particular editor view. 我正在使用ASP.NET MVC3应用程序,我无法在特定的编辑器视图中使用DropDownListFor来处理我的属性。
My model is a Person
and a person has a property that specifies it's "Person Type". 我的模型是一个
Person
,一个人有一个属性,指定它的“人物类型”。 PersonType
is a class that contains a name/description and an ID. PersonType
是一个包含名称/描述和ID的类。 I can access the available PersonType
s within the application through my static/shared class called ApplicationSettings
. 我可以通过名为
ApplicationSettings
静态/共享类访问应用程序中可用的PersonType
。
In the Edit Template view for my Person
I have created a SelectList
for debugging purposes: 在我的
Person
的Edit Template视图中,我创建了一个SelectList
用于调试目的:
@ModelType MyNamespace.Person
@Code
Dim pTypesSelectList As New SelectList(MyNamespace.ApplicationSettings.PersonTypes, "ID", "Name", Model.PersonType.ID)
End Code
I am then providing this SelectList
as a parameter to the DropDownListFor
that is bound to the PersonType
property of my Person
. 然后我将此
SelectList
作为参数提供给DropDownListFor
,该DropDownListFor
绑定到Person
的PersonType
属性。
I am also printing the Selected
property of each item in the SelectList
for debugging purposes: 我还打印
SelectList
中每个项目的Selected
属性以进行调试:
<div style="text-align: center; margin: 5px 0 0 0;">
<div>
@Html.LabelFor(Function(model) model.PersonType)
</div>
<div>
@Html.DropDownListFor(Function(model) model.PersonType, pTypesSelectList)
@Html.ValidationMessageFor(Function(model) model.PersonType)
<br />
<br />
<!-- The following is debugging code that shows the actual value-->
@Model.Type.Name
<br />
@Model.Type.ID
<br />
<br />
<!--This section is to show that the select list has properly selected the value-->
@For Each pitem In pTypesSelectList
@<div>
@pitem.Text selected: @pitem.Selected
</div>
Next
</div>
</div>
The view is bound to a Person
whose PersonType
property is "Person Type # 2" and I expect this to be selected; 该视图被绑定到一个
Person
,其PersonType
属性为“人员类型#2”,我期望这将被选择; however the HTML output of this code looks like this: 但是此代码的HTML输出如下所示:
<div style="text-align: center; margin: 5px 0 0 0;">
<div>
<label for="PersonType">PersonType</label>
</div>
<div>
<select id="PersonType" name="PersonType">
<option value="7e750688-7e00-eeee-0000-007e7506887e">Default Person Type</option>
<option value="87e5f686-990e-5151-0151-65fa7506887e">Person Type # 1</option>
<option value="a7b91cb6-2048-4b5b-8b60-a1456ba4134a">Person Type # 2</option>
<option value="8a147405-8725-4b53-b4b8-3541c2391ca9">Person Type # 3</option>
</select>
<span class="field-validation-valid" data-valmsg-for="PersonType" data-valmsg-replace="true"></span>
<br />
<br />
<!-- The following is debugging code that shows the actual value-->
Person Type # 2
<br />
a7b91cb6-2048-4b5b-8b60-a1456ba4134a
<br />
<br />
<!--This section is to show that the select list has properly selected the value-->
<div>
Default Person Type selected: False
</div>
<div>
Person Type # 1 selected: False
</div>
<div>
Person Type # 2 selected: True
</div>
<div>
Person Type # 3 selected: False
</div>
</div>
</div>
As you can see the printed Selected properties for the items in the SelectList shows that the 3rd item is "Selected". 如您所见,SelectList中项目的已打印Selected属性显示第3项是“Selected”。 But what is driving me crazy is that the option that corresponds with this is Not Selected.
但令我发疯的是,与此相对应的选项是Not Selected。
Generally, the Selected
property in SelectList
will be totally ignored by the HTML helpers unless there's no other option. 通常,除非没有其他选项,否则HTML帮助程序将完全忽略
SelectList
的Selected
属性。 If DropDownListFor
can find the value by other means, it will insist on using that value. 如果
DropDownListFor
可以通过其他方式找到该值,它将坚持使用该值。
In this case, it will use the value of model.PersonType
( .ToString()
) - but that's not what you want, judging by the model.PersonType.ID
you pass to the SelectList
. 在这种情况下,它将使用
model.PersonType
( .ToString()
)的值 - 但这不是您想要的,通过您传递给SelectList
的model.PersonType.ID
来判断。
More info in the answer here . 更多信息在这里答案 。
Workaround 解决方法
One easy workaround that should work would be to set: 一个应该工作的简单解决方法是设置:
ViewData["PersonType"] = model.PersonType.Id.
The helper looks in ModelState first if it exists - ie on POST. 如果存在,帮助程序首先在ModelState中查找 - 即在POST上。 This should work already, since
ModelState["PersonType"]
will be populated with the actual selected value that was posted. 这应该已经有效,因为
ModelState["PersonType"]
将填充已发布的实际选定值。
After ModelState it will look in ViewData
- with ViewData["PersonType"]
first, and only then ViewData.Model.PersonType
. 在ModelState之后,它将在
ViewData
查找 - 首先使用ViewData["PersonType"]
,然后只查看ViewData.Model.PersonType
。 In other words, you can "override" the value on your model with a value set directly on ViewData
. 换句话说,您可以使用直接在
ViewData
上设置的值“覆盖”模型上的值。
Better (IMO) solution 更好(IMO)的解决方案
The more general, "better practice", way to solve it (which also avoids having a custom model binder in order to translate the POST'ed ID back to PersonType
) is to use a ViewModel instead of working with full models in your view: 更通用的“更好的实践”,解决它的方法(也避免使用自定义模型绑定器将POST的ID转换回
PersonType
)是使用ViewModel而不是在视图中使用完整模型:
PersonTypeID
property - instead of PersonType
. PersonTypeID
属性 - 而不是PersonType
。 PersonType.ID
PersonType.ID
填充它 Html.DropDownListFor(Function(model) model.PersonTypeID)
, or Html.DropDownListFor(Function(model) model.PersonTypeID)
,或 Html.DropDownListFor(model => model.PersonTypeID)
Html.DropDownListFor(model => model.PersonTypeID)
PersonTypeID
=> PersonType
) back into the actual model in your POST Action. PersonTypeID
=> PersonType
)转换回POST Action中的实际模型。 This may seem like more work, but generally there tend to be many occasions in a project where you need more view-specific representations of your data to avoid too much inline Razor code - so translating from business objects to view models, while it may seem redundant and anti-DRY at times, tends to spare you of a lot of headaches. 这似乎更多的工作,但通常在项目中有很多场合需要更多特定于视图的数据表示,以避免过多的内联Razor代码 - 所以从业务对象转换到视图模型,尽管它看起来很像有时多余和反干,往往会让你免于很多麻烦。
Are you sure that your ModelState for "PersonType" key before rendering the view is empty? 在渲染视图之前,您确定“PersonType”键的ModelState是空的吗? As JimmiTh commented is going to search for the value in the ModelState first.
正如JimmiTh评论的那样,首先要在ModelState中搜索值。 It happened to me too, you can try
@Html.DropDownList("PersonTypeFake", Function(model) model.PersonType, pTypesSelectList)
and it should select the right option. 它也发生在我身上,你可以试试
@Html.DropDownList("PersonTypeFake", Function(model) model.PersonType, pTypesSelectList)
,它应该选择正确的选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.