繁体   English   中英

如何获取 Asp.Net Core DropdownList 以在 C# 枚举中显示 [Display()] 值?

[英]How do I get an Asp.Net Core DropdownList to show the [Display()] values in a C# enum?

我有一个看起来像这样的枚举:

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
        }

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

创建BoT.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”...。 的下拉菜单,示出了[显示()]名称:“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" })

问:有人能想到这种方法有什么缺点吗?

我使用 helper 类测试了以下内容并且它有效。 因此 valuesToDisplay = ["12 个月"、"24 个月"等...]:

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();
    }
}

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

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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM