Sorry if this is a dup, my searching turned up nothing.
I am using the following method to generate drop down lists for enum types (lifted from here: http://addinit.com/?q=node/54):
public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected)
{
if (!type.IsEnum)
throw new ArgumentException("Type is not an enum.");
if(selected != null && selected.GetType() != type)
throw new ArgumentException("Selected object is not " + type.ToString());
var enums = new List<SelectListItem>();
foreach (int value in Enum.GetValues(type))
{
var item = new SelectListItem();
item.Value = value.ToString();
item.Text = Enum.GetName(type, value);
if(selected != null)
item.Selected = (int)selected == value;
enums.Add(item);
}
return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, enums, "--Select--");
}
It is working fine, except for one thing. If I give the dropdown list the same name as the property on my model the selected value is not set properly. Meaning this works:
<%= Html.DropDownList("fam", typeof(EnumFamily), Model.Family)%>
But this doesn't:
<%= Html.DropDownList("family", typeof(EnumFamily), Model.Family)%>
Because I'm trying to pass an entire object directly to the controller method I am posting to, I would really like to have the dropdown list named for the property on the model. When using the "right" name, the dropdown does post correctly, I just can't seem to set the selected value.
I don't think this matters but I am running MVC 1 on mono 2.6
edit: I just tested this on windows, and I am seeing the same behavior
Try not using the int value for the enum / instead of:
item.Value = value.ToString();
use:
item.Value = Enum.GetName(type, value);
imo what's happening is that its automatically setting the selected value of the drop down to match the model - using the enum name instead of its int value. Remember that the view engine looks for the already selected value not only in the form posted (in cases when its already being posted) but also in the model+viewdata being passed to the view. Only if it doesn't find it there, it'll use the selected value you specified.
Actually, this is the solution. The same solution as mine in this question.
ASP.NET MVC - Html.DropDownList - Value not set via ViewData.Model
public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected)
{
if (!type.IsEnum)
throw new ArgumentException("Type is not an enum.");
if (selected != null && selected.GetType() != type)
throw new ArgumentException("Selected object is not " + type.ToString());
var enums = new List<SelectListItem>();
foreach (int value in Enum.GetValues(type))
{
var item = new SelectListItem();
item.Value = value.ToString();
item.Text = Enum.GetName(type, value);
if (selected != null)
item.Selected = (int)selected == value;
enums.Add(item);
}
// set ViewData first
helper.ViewData[name] = enums;
// pass in "null" intentionally into the DropDownList extension method
return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, null, "--Select--");
}
Using item.Value = Enum.GetName(type, value);
makes the drop down <option> values to be rendered as the Enum Names.
I personally prefer having int
values as postback.
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With