【问题标题】:How do I get an Asp.Net Core DropdownList to show the [Display()] values in a C# enum?如何获取 Asp.Net Core DropdownList 以显示 C# 枚举中的 [Display()] 值?
【发布时间】:2020-08-27 23:39:29
【问题描述】:

我有一个如下所示的枚举:

BoT_DropdownValues.cs:

   public class BoT_DropdownValues
    {
        public enum BlockSizes
        {
            [Display(Name = "12 Months")]
            M12,
            [Display(Name = "24 Months")]
            M24,
            [Display(Name = "36 Months")]
            M36,
            [Display(Name = "48 Months")]
            M48,
            [Display(Name = "60 Months")]
            M60
        }

我想从“选择”元素中选择一项:

CreateBoT.cshtml:

<div class="form-group" id="Q3_div">
    @Html.DropDownListFor(m => 
        m.BoT_Answers.Q3, 
        new SelectList(Enum.GetValues(typeof(BoT_DropdownValues.BlockSizes))),
        "Select One",
        new { @class = "custom-select", @id = "BoT_Answers_Q3" })
    ...

问题:

此语法在下拉列表中为我提供了“M12”、“M24”、“M36”、...。我会LIKE 向用户显示 [Display()] 名称:“12 个月”、“24 个月”等。

问:我可以使用 @Html.DropDownListFor() 的语法来实现此目的吗?

更新

我发现的大多数答案都涉及编写静态扩展类和许多额外的工作。我仍在寻找“更好的答案”,但现在这似乎给了我想要的一切:

           @Html.DropDownListFor(m =>
                m.BoT_Answers.Q3,
                new List<SelectListItem>
                {
                    new SelectListItem {Text="Select One", Value="", Selected=true },
                    new SelectListItem {Text="12 Months",  Value="12" },
                    new SelectListItem {Text="24 Months", Value="24" },
                    new SelectListItem {Text="36 Months", Value="36" },
                    new SelectListItem {Text="48 Months", Value="48" },
                    new SelectListItem {Text="60 Months", Value="60" }
                },
                new { @class = "custom-select", @id = "BoT_Answers_Q3" })

问:谁能想到这种方法的任何缺点

【问题讨论】:

  • 看看Html.GetEnumSelectList,也许this question会有所帮助

标签: c# asp.net-core razor


【解决方案1】:

我使用辅助类测试了以下内容并且它有效。所以 valuesToDisplay = ["12 months", "24 months" etc...]:

var valuesToDisplay = GetDisplayValues();

static List<string> GetDisplayValues() {
    List<string> ret = new List<string>();
    var enumValues = Enum.GetValues(typeof(BlockSizes));
    foreach (var value in enumValues)
    {
        ret.Add(EnumHelper<BlockSizes>.GetDisplayValue((BlockSizes)value));
    }
    return ret;
}

public static class EnumHelper<T>
{
    public static IList<T> GetValues(Enum value)
    {
        var enumValues = new List<T>();

        foreach (FieldInfo fi in value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public))
        {
            enumValues.Add((T)Enum.Parse(value.GetType(), fi.Name, false));
        }
        return enumValues;
    }

    public static T Parse(string value)
    {
        return (T)Enum.Parse(typeof(T), value, true);
    }

    public static IList<string> GetNames(Enum value)
    {
        return value.GetType().GetFields(BindingFlags.Static | BindingFlags.Public).Select(fi => fi.Name).ToList();
    }

    public static IList<string> GetDisplayValues(Enum value)
    {
        return GetNames(value).Select(obj => GetDisplayValue(Parse(obj))).ToList();
    }

    private static string lookupResource(Type resourceManagerProvider, string resourceKey)
    {
        foreach (PropertyInfo staticProperty in resourceManagerProvider.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
        {
            if (staticProperty.PropertyType == typeof(System.Resources.ResourceManager))
            {
                System.Resources.ResourceManager resourceManager = (System.Resources.ResourceManager)staticProperty.GetValue(null, null);
                return resourceManager.GetString(resourceKey);
            }
        }

        return resourceKey; // Fallback with the key name
    }

    public static string GetDisplayValue(T value)
    {
        var fieldInfo = value.GetType().GetField(value.ToString());

        var descriptionAttributes = fieldInfo.GetCustomAttributes(
            typeof(DisplayAttribute), false) as DisplayAttribute[];

        if (descriptionAttributes[0].ResourceType != null)
            return lookupResource(descriptionAttributes[0].ResourceType, descriptionAttributes[0].Name);

        if (descriptionAttributes == null) return string.Empty;
        return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Name : value.ToString();
    }
}

【讨论】:

  • 谢谢,但我绝对想要任何帮助类或扩展,如果我可以完全避免的话。我想将我的更改隔离到一个文件(如果可能的话,只是 .cshtml),并且我想让它尽可能简单。
【解决方案2】:

您将需要编写一个方法,或者使用其他人的。这是我的;

public static class EnumHelper<T> where T:struct, Enum{
    public static List<(T value, string display)> Values =
        typeof(T)
        .GetFields(BindingFlags.Static | BindingFlags.Public)
        .OrderBy(f => f.MetadataToken)
        .Select(f => (
            (T)f.GetValue(null),
            f.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName
                ?? f.GetCustomAttribute<DisplayAttribute>()?.Name
                ?? f.Name
        ))
        .ToList();
}

public static class Extensions{
    public static IEnumerable<SelectListItem> SelectList<T>(this IHtmlHelper html) where T:struct, Enum
        => EnumHelper<T>.Values.Select(v => new SelectListItem(v.display, v.value.ToString()));
}

<select asp-items="Html.SelectList<BlockSizes>()"></select>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 2010-11-03
    • 1970-01-01
    • 2015-08-31
    相关资源
    最近更新 更多