I'm trying to build out a settings page using reflection. Some options are enums, but the standard @Html.EditorFor()
gives a text box rather than a dropdown on these properties. I have an approach sort-of working using @Html.DropDownList()
, but I want the "for" helper to get the benefits of having the value pre-selected.
public class CycleSettings
{
//a bunch of sub-objects, like:
public SurveyConfiguration Survey { get; set; }
}
public class SurveyConfiguration
{
[JsonConverter(typeof(StringEnumConverter))]
[DisplayName("Display Survey Data")]
public DataDisplayFullOptions Data { get; set; }
}
public enum DataDisplayFullOptions
{
Available,
[Display(Name = "Coming Soon")]
ComingSoon,
Report
}
@foreach (var property in typeof(CycleSettings).GetProperties()) {
object temp = property.GetValue(Model.Settings.CycleSettings[Model.CurrentYear][Model.CurrentCycle]);
@Html.Label(property.Name)
<div style="padding-left: 20px">
@foreach (var subprop in temp.GetType().GetProperties())
{
object temp2 = subprop.GetValue(temp);
var label = Attribute.GetCustomAttribute(subprop, typeof (DisplayNameAttribute));
@Html.Label(label != null ? ((DisplayNameAttribute)label).DisplayName : subprop.Name,new {@style="padding-right: 20px"})
@(temp2.GetType().IsEnum ? Html.EnumDropDownListFor((m) => temp2) : Html.EditorFor((m) => temp2)) //error occurs here on EnumDropDownListFor path
/*Html.DropDownList(subprop.Name, EnumHelper.GetSelectList(temp2.GetType()))*/ //this worked, but I am trying to use the EnumDropDownListFor to get the correct property selected on load
<br/>
}
</div>
}
[ArgumentException: Return type 'System.Object' is not supported. Parameter name: expression]
System.Web.Mvc.Html.SelectExtensions.EnumDropDownListFor(HtmlHelper`1 htmlHelper, Expression`1 expression, String optionLabel, IDictionary`2 htmlAttributes) +1082
System.Web.Mvc.Html.SelectExtensions.EnumDropDownListFor(HtmlHelper`1 htmlHelper, Expression`1 expression, String optionLabel) +90
EDIT: Just tried this-- no more error, but still not selecting the right value:
Html.DropDownListFor((m) => temp2, EnumHelper.GetSelectList(temp2.GetType()))
The answer turned out to be pretty simple. I was close with this attempt:
Html.DropDownListFor((m) => temp2, EnumHelper.GetSelectList(temp2.GetType()))
I just needed to override the GetSelectList
:
Html.DropDownListFor((m) => temp2, EnumHelper.GetSelectList(temp2.GetType(), (Enum)temp2))