将枚举列表转换为SelectList并保持显示?

时间:2019-12-06 19:54:00

标签: c# razor html.dropdownlistfor

我们有一个由选项列表驱动的视图。根据初始条件,将创建一个DropDownList,其中包含用户下一步的选择。此列表填充有自定义枚举中包含的较大选项列表。

所以我们有一个像这样的枚举:

public enum ChangeMode
{
    [Display(Name ="Please Select")] InitialState,
    [Display(Name = "Change A Thing")] ChangeThing,
    //...
    [Display(Name = "Do a Dance")] DoADance,
    FinishedSuccess,
    FinishedFailure
}

在视图的控制器中,我们构建了一个List,其中包含用户的所有有效选项,而从不完整列表。

if( /*Irrelevant determining characteristic*/ )
{//Valid choices for this option
    model.ValidModes = new List<ChangeMode> { ChangeMode.InitialState, ChangeMode.ChangeThing};
}

然后我们基于模型的ChangeModes列表在视图中创建一个DropDownList

    @Html.DropDownListFor(m => Model.AlterMethod, new SelectList(Model.ValidModes))

除了生成的DDL不包括分配每种模式的用户友好名称(而是显示Enum的开发人员可读值(例如,“ InitialState”))之外,所有其他方法都工作正常。如何更改此设置以使View正确呈现下拉列表,以便它使用Display(Name)作为DDL的文本?

2 个答案:

答案 0 :(得分:1)

您需要从Enum属性中获取值。为此,您需要一个将返回属性的辅助方法。

这是访问Enum属性的帮助方法:

public T GetAttribute<T>(Enum _enum) where T : Attribute
{
    return 
        (T)_enum.GetType()
                .GetField(Enum.GetName(_enum.GetType(), _enum))
                .GetCustomAttribute(typeof(T));
}

用法:

var name = GetAttribute<DisplayAttribute>(ChangeMode.InitialState).Name;

答案 1 :(得分:0)

  

ASP.NET Core附带了用于为以下对象生成SelectListItem的帮助器:   任何枚举。

这意味着,如果您有TEnum类型的枚举,则可以在您的列表中生成可用选项 使用asp-items="Html.GetEnumSelectList<TEnum>()"查看。

更改:

@Html.DropDownListFor(m => Model.AlterMethod, new SelectList(Model.ValidModes))

收件人:

<select asp-for="AlterMethod" asp-items="Html.GetEnumSelectList<Enums.ChangeMode>()"></select>

或者,如果您只想要ValidModes中的值:

<select asp-for="AlterMethod" asp-items="Html.GetEnumSelectList(typeof(Model.ValidModes))"></select>