【问题标题】:Is there a function of Html.GetEnumSelectList<Enum>() that will set the value of the option to the value of said Enum?是否有 Html.GetEnumSelectList<Enum>() 的函数将选项的值设置为所述 Enum 的值?
【发布时间】:2019-11-30 01:32:57
【问题描述】:

当为以下枚举使用内置 Html.GetEnumSelectList() 时:

public enum Country {
        [Display(Name="United States")] US,
        [Display(Name="Canada")] CA
}

它会生成以下html:

<select id="prefix" class="form-control">
    <option value="0">United States</option>
    <option value="1">Canada</option>
</select>

有没有办法将值设置为枚举的值而不是索引?

我为我需要的东西写了一个扩展,但它是如此基础,以至于 C# 团队错过了它感觉很奇怪,所以我很好奇我是否这样做了

using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace HotelMaven.Extensions {
    public static class HtmlExtensions {
        public static IEnumerable<SelectListItem> GetEnumSelectList<TEnum>(this IHtmlHelper html, TEnum selectedValue) where TEnum : struct {
            var values = Enum.GetValues(typeof(TEnum))
                .Cast<TEnum>();
            return values.Select(eachValue => new SelectListItem {
                Text = eachValue.GetType().GetField(eachValue.ToString()).GetCustomAttribute<DisplayAttribute>()?.Name,
                Value = eachValue.ToString(),
                Selected = eachValue.Equals(selectedValue)
            });
        }

        public static IEnumerable<SelectListItem> GetEnumSelectList<TEnum>(this IHtmlHelper html, bool isValueUsedForValue) where TEnum : struct {
            if (!isValueUsedForValue) return html.GetEnumSelectList<TEnum>();
            var values = Enum.GetValues(typeof(TEnum))
                .Cast<TEnum>();
            return values.Select(eachValue => new SelectListItem {
                Text = eachValue.GetType().GetField(eachValue.ToString()).GetCustomAttribute<DisplayAttribute>()?.Name,
                Value = eachValue.ToString()
            });
        }
    }
}

这导致了我正在寻找的结果:

<select id="prefix" class="form-control">
<option selected="selected" value="US">United States</option>
<option value="CA">Canada</option>
</select>

使用:

<select asp-items="Html.GetEnumSelectList<Country>(Country.US)" id="country" class="form-control"></select>

【问题讨论】:

    标签: asp.net-core razor


    【解决方案1】:

    你可以对枚举使用属性并获取并使用它,例如此代码获取DisplayAttribute值。

    public static string GetDisplayName(this Enum value)
            {
                if (value == null) return String.Empty;
                if (Cache.ContainsKey(value))
                    return Cache[value];
    
                var enumType = value.GetType();
                var enumName = Enum.GetName(enumType, value);
                var member = enumType.GetMember(enumName)[0];
    
                var attributes = member.GetCustomAttributes(typeof(DisplayAttribute), false);
    
                var outString = ((DisplayAttribute)attributes[0]).ResourceType != null
                                    ? ((DisplayAttribute)attributes[0]).GetName()
                                    : ((DisplayAttribute)attributes[0]).Name;
    
                Cache.Add(value, outString);
    
                return outString;
            }
    

    我认为你可以为每个枚举值定义属性(通过自定义或可用属性,如你使用的显示属性)并将值存储在此属性中,并将其用于选项值或任何位置。

    【讨论】:

    • 谢谢,但我专门寻找设置选择列表的值,而不是显示。显示由我在枚举中显示的属性处理。
    • 我的意思是,将选择列表项的值放在一个属性中,比如显示。你使用按属性显示,那么你也可以通过另一个属性使用值。
    【解决方案2】:

    您应该使用与默认名称 GetEnumSelectList 不同的名称来定义扩展名

    public static class HtmlExtensions
    {
        public static IEnumerable<SelectListItem> GetEnumValueSelectList<TEnum>(this IHtmlHelper htmlHelper) where TEnum : struct
        {
            return new SelectList(Enum.GetValues(typeof(TEnum)).OfType<Enum>()
                .Select(x =>
                    new SelectListItem
                    {
                        Text = x.GetType().GetField(x.ToString()).GetCustomAttribute<DisplayAttribute>()?.Name,
                        Value = x.ToString()
                    }), "Value", "Text");
        }
    }
    

    及用法:

    <select  class="form-control" asp-items="Html.GetEnumValueSelectList<Country>()"></select>
    

    【讨论】:

    • 不确定我是否理解。由于我扩展了内置函数的基本功能,因此方法重载在这里是可行的。
    【解决方案3】:

    如果你愿意,你可以通过 JavaScript 解决它 例如:

    <select id="status" name="TicketStatus" asp-items="Html.GetEnumSelectList(typeof (TicketSystem.Models.EnumStatus))" class="form-control" >
        <option value="-1">All</option>
    </select>
    <script>
        var st = document.getElementById('status');
        for (x of st.options) {
            x.value = x.innerText;
        }
    </script>
    

    【讨论】:

    • 欢迎来到 StackOverflow。请提供一些解释,而不仅仅是代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多