DropDownList不选择SelectList中的选定项

时间:2013-08-16 16:00:35

标签: asp.net-mvc asp.net-mvc-3 html.dropdownlistfor selectlist

我正在使用ASP.NET MVC3应用程序,我无法在特定的编辑器视图中使用DropDownListFor来处理我的属性。

我的模型是Person,并且一个人有一个属性,指定它是“人物类型”。 PersonType是一个包含名称/描述和ID的类。我可以通过名为PersonType的静态/共享类访问应用程序中的可用ApplicationSettings

在我的Person的编辑模板视图中,我创建了一个SelectList用于调试目的:

@ModelType MyNamespace.Person
@Code
    Dim pTypesSelectList As New SelectList(MyNamespace.ApplicationSettings.PersonTypes, "ID", "Name", Model.PersonType.ID)
End Code

然后我将此SelectList作为参数提供给绑定到DropDownListFor的{​​{1}}属性的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> Person属性为“Person Type#2”的PersonType,我希望这个被选中;但是此代码的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>

如您所见,SelectList中项目的已打印Selected属性显示第3项是“Selected”。但令我发疯的是,与此相对应的选项是Not Selected。

2 个答案:

答案 0 :(得分:6)

通常,除非没有其他选项,否则HTML帮助程序将完全忽略Selected中的SelectList属性。如果DropDownListFor可以通过其他方式找到该值,则坚持使用该值。

在这种情况下,它会使用model.PersonType.ToString())的值 - 但这不是您想要的,请通过传递给model.PersonType.ID的{​​{1}}来判断

the answer here中的更多信息。

解决方法

一个应该起作用的简单解决方法是设置:

SelectList

如果存在,帮助程序首先在ModelState中查找 - 即在POST时。这应该已经有效,因为ViewData["PersonType"] = model.PersonType.Id. 将填充已发布的实际选定值。

在ModelState之后,它将首先查看ModelState["PersonType"] - ViewData,然后ViewData["PersonType"]。换句话说,您可以使用直接在ViewData.Model.PersonType上设置的值“覆盖”模型上的值。

更好(IMO)解决方案

更通用,“更好的做法”,解决它的方法(也避免使用自定义模型绑定器将POST的ID转换回ViewData)是使用ViewModel而不是工作在您的视图中使用完整模型:

  • 拥有PersonType财产 - 而不是PersonTypeID
  • 使用PersonType
  • 填充它
  • 在您的视图中使用此功能
    • VB.NET:PersonType.ID
    • C#:Html.DropDownListFor(Function(model) model.PersonTypeID)
  • 当表单被POST时,将ViewModel(包括Html.DropDownListFor(model => model.PersonTypeID) =&gt; PersonTypeID)转换回POST Action中的实际模型。

这似乎更多的工作,但通常在项目中有很多场合需要更多特定于视图的数据表示,以避免过多的内联Razor代码 - 从业务对象转换为视图模型,同时它有时似乎是多余的,反DRY,往往会让你免于很多麻烦。

答案 1 :(得分:1)

在渲染视图之前,您确定“PersonType”键的ModelState是空的吗?正如JimmiTh评论的那样,首先要在ModelState中搜索值。它也发生在我身上,你可以试试 @Html.DropDownList("PersonTypeFake", Function(model) model.PersonType, pTypesSelectList),它应该选择正确的选项。