【问题标题】:How to use MVC Html Helper .DropDownListFor<> with an Enum如何使用带有枚举的 MVC Html Helper .DropDownListFor<>
【发布时间】:2011-05-26 23:22:03
【问题描述】:

在我的 MVC 3 Razor 应用程序中,我有一个带有枚举的模型..

模型示例:

public class EmployeeModel
{
 public enum Title
 {
  Accountant = 111,
  Sales = 222,
  Production = 333 
 }

 [Required]
 public string Name {get; set;}

 [Required]
 public Title JobTitle {get; set;}
}

在我看来,我想使用 Html 助手来构建一个 Html 表单...

查看示例:

@model ..Models.EmployeeModel

@using (Html.BeginForm())
{
 @Html.LabelFor(m => m.Name)
 @Html.TextBoxFor(m => m.Name)
 <br>

 @Html.LabelFor(m => m.JobTitle)
 @Html.DropDownListFor(m => m.JobTitle, ??How do I get Title enum values??)
 <br>

 <input type="submit />
}

我试图实现的 DropDownListFor 的输出如下所示: 注意选项值与枚举的初始化值匹配

<select name="JobTitle">
 <option value="-1">Choose a Job Title</option>
 <option value="111">Accountant</option>
 <option value="222">Sales</option>
 <option value="333">Production</option>
</select>

如何让 DropDownListFor 帮助器根据模型的 Title 枚举创建选择/选项元素?

另外,是否可以让 DropDownListFor 帮助器添加一个额外的(不是枚举的一部分),类似于上面示例中的“选择职位”选项?

【问题讨论】:

标签: asp.net-mvc asp.net-mvc-3 razor html-helper html.dropdownlistfor


【解决方案1】:

您可能会得到一个带有枚举值名称的String[],并从中创建一个下拉列表。在您的视图模型中,添加 SelectListItem 类型的属性 Titles 并将枚举值和名称添加到其中。您可以通过System.Enum类型获取名称和值。

var defaultItem = new SelectListItem();
defaultItem.Value = -1;
defaultItem.Text = "Choose a title";
defaultItem.Selected = true;
model.TitleSelectItems.add(defaultItem);

String[] names = System.Enum.GetNames(typeof(Title));
Int[] values = System.Enum.GetValues(typeof(Title));

for (int i = 0; i<names.Length; i++)
{
    var item = new SelectListItem();
    item.Text = names[i];
    item.Value = values[i];
    model.TitleSelectItems.Add(item);
}

这有点难看,但它会起作用。

【讨论】:

    【解决方案2】:

    我只是偶然发现了这个StackO question/answer - 不仅我的问题在这里完全重复,而且answer given by Mike McLaughlin 是我见过的将DropdownListFor&lt;&gt;Enums 结合使用的最佳解决方案。具体来说,迈克将我们指向a solution that he found by Morgan Leroi

    摩根的快速解决方案是:

    @Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States))))
    

    但是,Morgan 做了一个扩展,使 DropDownListFor&lt;&gt; 与枚举的实现更加紧凑。你可以download Morgan's Visual Studio Solution here.

    也就是说,我认为我们应该关闭这个问题,因为它是完全重复的。

    【讨论】:

    • 默认项呢?
    【解决方案3】:

    解决办法

    public enum Months
    {
    January=1,
    February=2,
    March=3,
    April =4,
    May=5,
    June=6
    }
    
    public ActionResult Index()
    {
    
    ViewBag.Months = (from Months m in Enum.GetValues(typeof(Months))
                    select new SelectListItem { Text = m.ToString(), Value = Convert.ToUInt16(m).ToString() });
    
    return View();  
    }
    

    在 DropDownList 中添加 ViewBag 名称:

    <%=Html.DropDownList("Months") %>
    

    【讨论】:

      【解决方案4】:

      这是一种使用 Html Helpers 的方法:

      型号

      public class Person
      {
          public string Name { get; set; }
          public JobTitle Job { get; set; }
          public enum JobTitle
          {
              Accountant = 111,
              Sales = 222,
              Production = 333
          }
      }
      

      查看

      @model MvcApplication1.Models.Person
      
      @{
          ViewBag.Title = "Index";
      }
      
      @using (Html.BeginForm())
      {
          @Html.TextBoxFor(n => n.Name)
          @Html.DropDownListFor(c => c.Job, new[]{
              new SelectListItem() {Text = MvcApplication1.Models.Person.JobTitle.Accountant.ToString(), 
                  Value=((int)MvcApplication1.Models.Person.JobTitle.Accountant).ToString()}
              ,new SelectListItem() {Text = MvcApplication1.Models.Person.JobTitle.Production.ToString(), 
                  Value=((int)MvcApplication1.Models.Person.JobTitle.Production).ToString()}
              ,new SelectListItem() {Text = MvcApplication1.Models.Person.JobTitle.Sales.ToString(),
                  Value=((int)MvcApplication1.Models.Person.JobTitle.Sales).ToString()}}
                  , "Choose a Job Title")                               
      }
      

      HTML 输出

      <!DOCTYPE html>
      <html>
      <head>
          <title>Index</title>
      </head>
      <body>
      <form action="/" method="post">
      <input id="Name" name="Name" type="text" value="" />
      <select id="Job" name="Job">
      <option value="">Choose a Job Title</option>
      <option value="111">Accountant</option>
      <option value="333">Production</option>
      <option value="222">Sales</option>
      </select>
      </form>
      </body>
      </html>
      

      【讨论】:

        【解决方案5】:

        这里提供了一个封装的 HTML 助手扩展:

        http://www.spicelogic.com/Journal/ASP-NET-MVC-DropDownListFor-Html-Helper-Enum-5

        源代码快照:

        您可以从该链接下载该项目的完整源代码。

        【讨论】:

        【解决方案6】:

        我用这个扩展解决了这个问题:

        public static SelectList ToSelectListWithDefault<TEnum>(this TEnum enumObj, string defValue, string defText) where TEnum : IConvertible
        {
            var values = new List<SelectListItem>();
            var defItem = new SelectListItem() { Value = defValue, Text = defText };
            values.Add(defItem);
            foreach (TEnum e in Enum.GetValues(typeof(TEnum)))
            {
                values.Add(new SelectListItem() { Value = e.ToInt16(null).ToString(), Text = e.ToString() });
            }
        
            return new SelectList(values, "Value", "Text", defItem);
        }   
        

        (我在 SO 上找到了扩展名,但没有默认值)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多