How to use MVC Html Helper .DropDownListFor<> with an Enum
In my MVC 3 Razor app, I have a Model with an enum..
Model Example:
public class EmployeeModel
{
public enum Title
{
Accountant = 111,
Sales = 222,
Production = 333
}
[Required]
public string Name {get; set;}
[Required]
public Title JobTitle {get; set;}
}
In my View I would like to use the Html helpers to build an Html Form...
View Example:
@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 />
}
The output of the DropDownListFor that I trying to achieve would look lik开发者_StackOverflowe this: Note the option values match the initialized values of the enum
<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>
How do I get the DropDownListFor<> helper to create a select/option element based on the Title enum of the Model?
Also, is it possible to have the DropDownListFor<> helper to add an extra (that is not part of the enum) similar to the "Choose a Job Title" option in the example above?
You could possibly get a String[]
with the names of the enum values and create a dropdown from that. In your view model, add a property Titles
of type SelectListItem
and add the enum values and names to that. You can get the names and values through the System.Enum
type.
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);
}
It's kind of ugly, but it'll work.
I just stumbled on this StackO question/answer - not only is my question here an exact duplicate, but the answer given by Mike McLaughlin is the best solution I've seen for using DropdownListFor<>
with Enums
. Specifically, Mike points us to a solution that he found by Morgan Leroi
Morgan's quick solution is:
@Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States))))
But, Morgan has made an Extension that makes the implementation of the DropDownListFor<>
with enums even more compact. You can download Morgan's Visual Studio Solution here.
That said, I think we should close this question as it's an exact duplicate.
Here is the solution
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();
}
Add ViewBag name in DropDownList :
<%=Html.DropDownList("Months") %>
Here's a way using Html Helpers:
Model
public class Person
{
public string Name { get; set; }
public JobTitle Job { get; set; }
public enum JobTitle
{
Accountant = 111,
Sales = 222,
Production = 333
}
}
View
@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 Output
<!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>
An encapsulated HTML Helper Extension is available here :
http://www.spicelogic.com/Journal/ASP-NET-MVC-DropDownListFor-Html-Helper-Enum-5
the source code snapshot:
You can download the full source code of the project from the link.
I solved it with this extension:
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);
}
(I found the extension on SO, but without the default value)
精彩评论