Fri*_*ale 3 asp.net-mvc selectlist html.dropdownlistfor asp.net-mvc-3
我正在使用ASP.NET MVC3应用程序,我无法在特定的编辑器视图中使用DropDownListFor来处理我的属性.
我的模型是a Person和一个人有一个属性,指定它的"人物类型".PersonType是一个包含名称/描述和ID的类.我可以PersonType通过我的静态/共享类访问应用程序中的可用s ApplicationSettings.
在我的编辑模板视图中,我Person创建了一个SelectList用于调试的目的:
@ModelType MyNamespace.Person
@Code
Dim pTypesSelectList As New SelectList(MyNamespace.ApplicationSettings.PersonTypes, "ID", "Name", Model.PersonType.ID)
End Code
Run Code Online (Sandbox Code Playgroud)
然后我提供这个SelectList作为参数DropDownListFor绑定到PersonType我的属性Person.
我也在打印Selected每个项目的属性以SelectList进行调试:
<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>
Run Code Online (Sandbox Code Playgroud)
该视图绑定到Person其PersonType属性为"Person Type#2",我希望这个被选中; 但是此代码的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>
Run Code Online (Sandbox Code Playgroud)
如您所见,SelectList中项目的已打印Selected属性显示第3项是"Selected".但令我发疯的是,与此相对应的选项是Not Selected.
通常,除非没有其他选项,否则HTML帮助程序将完全忽略Selected属性SelectList.如果DropDownListFor可以通过其他方式找到该值,它将坚持使用该值.
在这种情况下,它将使用model.PersonType(.ToString())的值- 但这不是你想要的,通过model.PersonType.ID你传递到SelectList.
更多信息在这里答案.
解决方法
一个应该工作的简单解决方法是设置:
ViewData["PersonType"] = model.PersonType.Id.
Run Code Online (Sandbox Code Playgroud)
如果存在,帮助程序首先在ModelState中查找 - 即在POST上.这应该已经有效,因为ModelState["PersonType"]将填充已发布的实际选定值.
在ModelState之后,它将首先查看ViewData- ViewData["PersonType"]然后才会查看ViewData.Model.PersonType.换句话说,您可以使用直接设置的值"覆盖"模型上的值ViewData.
更好(IMO)的解决方案
更通用的"更好的练习",解决它的方法(也避免使用自定义模型绑定器将POST的ID转换回来PersonType)是使用ViewModel而不是在视图中使用完整模型:
PersonTypeID特性-代替PersonType.PersonType.IDHtml.DropDownListFor(Function(model) model.PersonTypeID)或者Html.DropDownListFor(model => model.PersonTypeID)PersonTypeID=> PersonType)转换回POST Action中的实际模型.这似乎更多的工作,但通常在项目中有很多场合需要更多特定于视图的数据表示,以避免过多的内联Razor代码 - 所以从业务对象转换到视图模型,尽管它看起来很像有时多余和反干,往往会让你免于很多麻烦.
| 归档时间: |
|
| 查看次数: |
3984 次 |
| 最近记录: |