2015-11-14 41 views
1

我有一个基本的形式让用户然后把它贴并保存到数据库中输入的细节 - 这工作正常,没有任何问题:@ Html.EnumDropDownListFor - 下拉值未设置

@model R32.Register.Models.RegisterCar 
@{ 
    ViewBag.Title = "Edit Your R32"; 
} 

<h2>Edit R32</h2> 
<div> 
    @using (Html.BeginForm("UpdateCar", "Garage", FormMethod.Post)) 
    { 
     @Html.ValidationSummary(true) 
     <fieldset> 
      <legend>Enter details</legend> 
      <ol>     
       <li> 
        @Html.LabelFor(m => m.NumberPlate) 
        @Html.EditorFor(m => m.NumberPlate, new { @class = "form-control" }) 
        @Html.ValidationMessageFor(m => m.NumberPlate) 
       </li>      
       <li> 
        @Html.LabelFor(m => m.Edition) 
        @Html.EnumDropDownListFor(m => m.Edition, "Select an edition:", new { @class = "form-control" }) 
        @Html.ValidationMessageFor(m => m.Edition) 
       </li> 
       <li> 
        @Html.LabelFor(m => m.Colour) 
        @Html.EnumDropDownListFor(m => m.Colour, "Select a colour:", new { @class = "form-control" }) 
        @Html.ValidationMessageFor(m => m.Colour) 
       </li>      
      </ol> 
      <input type="submit" value="Save Changes" /> 
     </fieldset> 
    } 
</div> 

型号片段:

[Required] 
[Display(Name="Edition")] 
public MkEnum? Edition { get; set; } 

枚举:

public enum MkEnum 
{ 
    [Display(Name="Mk4")] 
    Mk4 = 1, 
    [Display(Name="Mk5")] 
    Mk5 = 2 
} 

控制呈现为预计,随着艾迪下拉列表有三个值:“选择版本”,“Mk4”和“Mk5”。

用户可以选择一个版本,控制被验证,然后发布到控制器。

帖子成功,所有选定的值都发送到控制器 - 应用程序然后将数据保存在数据库中,依此类推,没有任何问题。

问题是,当我将此模型传递回相同的视图以允许用户编辑保存的数据时,保存的枚举值不会被设置为下拉列表中的选定值。

我可以确认任何已保存的字符串值(例如此示例中的NumberPlate)将被传回到视图中并加载到UI中。

在视图模型渲染断点时,我可以确认我的@model包含枚举属性的保存值 - 例如Edition - 但最终结果是“Select an edition:”下拉列表呈现包含预期的下拉值,但它的值是默认的“选择版本:”而不是通过传入的实际值。 m.Edition。

我已经能够使用DropDownListFor得到这个工作 - 但在理解为什么这不工作使用EnumDropDownListFor时有困难,因为这显然是一个更优雅的解决方案。

有没有人对此有任何帮助/建议?

+0

据我所知,EnumDropDownList是不可能的。您可以编写一个通用扩展方法将枚举转换为SelectLists。 [This](http://geeksharp.com/2011/11/02/power-up-your-enumerations/)示例代码可能会有所帮助。 –

+0

它应该工作。您是否尝试将代码放入示例MVC应用程序中,并检查发生了什么? –

+0

如果将模型传递给视图时,“版本”的值为“MkEnum.Mk5”,则渲染视图时将选择第三个选项。如果没有,你的代码还有其他错误。显示控制器方法。 (作为测试,只需在视图中添加'@DisplayFor(m => m.Edition)'来查看输出是什么) –

回答

0

好了,从我可以看到这个问题是通过使用ActionLink的传回的完整模型引起正在编辑的项目。所有东西都被发送回查询字符串,所以我的Enum值以下面的方式传递给控制器​​:mkEnum = Mk4。

我当时正在加载UpdateCar视图,如上面在我的示例中所看到的 - 但查询字符串值在回调视图时被持久化。

EnumDropDownListFor无法将枚举的文本值解释/转换为其实际值 - 如果手动将查询字符串编辑为mkEnum = 1,则将正确的值加载到ViewModel中。

除了这个问题,它不是一个很好的解决方案,将整个模型传递回控制器。 我修改了代码以传回正在编辑的项目的单个标识 - 然后控制器验证用户是否有权访问该标识,从数据库中检索模型,然后将其传递回与上例中相同的视图。

使用此更改,我的下拉列表正在更新其值,没有任何问题。

TLDR;如果遇到此问题,请检查以确保在加载视图并使用EnumDropDownListFor时,在查询字符串中没有模型属性,特别是其字符串值表示的枚举值。

0

我刚碰到这个问题。发生这种情况是因为枚举类型的字段被传回给序列化为浏览器枚举名称的浏览器,但@ Html.EnumDropDownListFor将其选项值作为整数生成。浏览器无法匹配这两个,所以下拉菜单保持其默认选择。

有3种方法可以解决这个问题。

  1. 获取视图模型的枚举字段以正确地序列化为int。
  2. 编写一个使用枚举名称作为选项值的下拉生成器。
  3. 使用JavaScript来手动选择选项(包括这里剃刀语法)

    ​​
+0

这与我发现的修复有关 - 在我的案例中,解决方案是确定我没有' t需要将Enum字符串值作为查询字符串的一部分传回给View。 – KrashTest