How to get the Display Name Attribute of an Enum member via MVC razor code?

后端 未结 20 2371
孤街浪徒
孤街浪徒 2020-11-22 09:30

I\'ve got a property in my model called \"Promotion\" that its type is a flag enum called \"UserPromotion\". Members of my enum have display attributes set as follows:

相关标签:
20条回答
  • 2020-11-22 09:31

    Based on previous answers I've created this comfortable helper to support all DisplayAttribute properties in a readable way:

    public static class EnumExtensions
        {
            public static DisplayAttributeValues GetDisplayAttributeValues(this Enum enumValue)
            {
                var displayAttribute = enumValue.GetType().GetMember(enumValue.ToString()).First().GetCustomAttribute<DisplayAttribute>();
    
                return new DisplayAttributeValues(enumValue, displayAttribute);
            }
    
            public sealed class DisplayAttributeValues
            {
                private readonly Enum enumValue;
                private readonly DisplayAttribute displayAttribute;
    
                public DisplayAttributeValues(Enum enumValue, DisplayAttribute displayAttribute)
                {
                    this.enumValue = enumValue;
                    this.displayAttribute = displayAttribute;
                }
    
                public bool? AutoGenerateField => this.displayAttribute?.GetAutoGenerateField();
                public bool? AutoGenerateFilter => this.displayAttribute?.GetAutoGenerateFilter();
                public int? Order => this.displayAttribute?.GetOrder();
                public string Description => this.displayAttribute != null ? this.displayAttribute.GetDescription() : string.Empty;
                public string GroupName => this.displayAttribute != null ? this.displayAttribute.GetGroupName() : string.Empty;
                public string Name => this.displayAttribute != null ? this.displayAttribute.GetName() : this.enumValue.ToString();
                public string Prompt => this.displayAttribute != null ? this.displayAttribute.GetPrompt() : string.Empty;
                public string ShortName => this.displayAttribute != null ? this.displayAttribute.GetShortName() : this.enumValue.ToString();
            }
        }
    
    0 讨论(0)
  • 2020-11-22 09:33

    I'm sorry to do this, but I couldn't use any of the other answers as-is and haven't time to duke it out in the comments.

    Uses C# 6 syntax.

    static class EnumExtensions
    {
        /// returns the localized Name, if a [Display(Name="Localised Name")] attribute is applied to the enum member
        /// returns null if there isnt an attribute
        public static string DisplayNameOrEnumName(this Enum value)
        // => value.DisplayNameOrDefault() ?? value.ToString()
        {
            // More efficient form of ^ based on http://stackoverflow.com/a/17034624/11635
            var enumType = value.GetType();
            var enumMemberName = Enum.GetName(enumType, value);
            return enumType
                .GetEnumMemberAttribute<DisplayAttribute>(enumMemberName)
                ?.GetName() // Potentially localized
                ?? enumMemberName; // Or fall back to the enum name
        }
    
        /// returns the localized Name, if a [Display] attribute is applied to the enum member
        /// returns null if there is no attribute
        public static string DisplayNameOrDefault(this Enum value) =>
            value.GetEnumMemberAttribute<DisplayAttribute>()?.GetName();
    
        static TAttribute GetEnumMemberAttribute<TAttribute>(this Enum value) where TAttribute : Attribute =>
            value.GetType().GetEnumMemberAttribute<TAttribute>(value.ToString());
    
        static TAttribute GetEnumMemberAttribute<TAttribute>(this Type enumType, string enumMemberName) where TAttribute : Attribute =>
            enumType.GetMember(enumMemberName).Single().GetCustomAttribute<TAttribute>();
    }
    
    0 讨论(0)
  • 2020-11-22 09:34

    One liner - Fluent syntax

    public static class Extensions
    {
        /// <summary>
        ///     A generic extension method that aids in reflecting 
        ///     and retrieving any attribute that is applied to an `Enum`.
        /// </summary>
        public static TAttribute GetAttribute<TAttribute>(this Enum enumValue) 
                where TAttribute : Attribute
        {
            return enumValue.GetType()
                            .GetMember(enumValue.ToString())
                            .First()
                            .GetCustomAttribute<TAttribute>();
        }
    }
    

    Example

    public enum Season 
    {
       [Display(Name = "It's autumn")]
       Autumn,
    
       [Display(Name = "It's winter")]
       Winter,
    
       [Display(Name = "It's spring")]
       Spring,
    
       [Display(Name = "It's summer")]
       Summer
    }
    
    public class Foo 
    {
        public Season Season = Season.Summer;
    
        public void DisplayName()
        {
            var seasonDisplayName = Season.GetAttribute<DisplayAttribute>();
            Console.WriteLine("Which season is it?");
            Console.WriteLine (seasonDisplayName.Name);
        } 
    }
    

    Output

    Which season is it?
    It's summer

    0 讨论(0)
  • 2020-11-22 09:34

    I want to contribute with culture-dependent GetDisplayName enum extension. Hope this will be usefull for anyone googling this answer like me previously:

    "standart" way as Aydin Adn and Todd mentioned:

        public static string GetDisplayName(this Enum enumValue)
        {
            return enumValue
                .GetType()
                .GetMember(enumValue.ToString())
                .First()
                .GetCustomAttribute<DisplayAttribute>()
                .GetName();
        }
    

    "Culture-dependent" way:

        public static string GetDisplayName(this Enum enumValue, CultureInfo ci)
        {
            var displayAttr = enumValue
                .GetType()
                .GetMember(enumValue.ToString())
                .First()
                .GetCustomAttribute<DisplayAttribute>();
    
            var resMan = displayAttr.ResourceType?.GetProperty(@"ResourceManager", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null, null) as ResourceManager;
    
            return resMan?.GetString(displayAttr.Name, ci) ?? displayAttr.GetName();
        }
    
    0 讨论(0)
  • 2020-11-22 09:35

    combining all edge-cases together from above:

    • enum members with base object members' names (Equals, ToString)
    • optional Display attribute

    here is my code:

    public enum Enum
    {
        [Display(Name = "What a weird name!")]
        ToString,
    
        Equals
    }
    
    public static class EnumHelpers
    {
        public static string GetDisplayName(this Enum enumValue)
        {
            var enumType = enumValue.GetType();
    
            return enumType
                    .GetMember(enumValue.ToString())
                    .Where(x => x.MemberType == MemberTypes.Field && ((FieldInfo)x).FieldType == enumType)
                    .First()
                    .GetCustomAttribute<DisplayAttribute>()?.Name ?? enumValue.ToString();
        }
    }
    
    void Main()
    {
        Assert.Equals("What a weird name!", Enum.ToString.GetDisplayName());
        Assert.Equals("Equals", Enum.Equals.GetDisplayName());
    }
    
    0 讨论(0)
  • 2020-11-22 09:40

    Using MVC5 you could use:

    public enum UserPromotion
    {
       None = 0x0,
    
       [Display(Name = "Send Job Offers By Mail")]
       SendJobOffersByMail = 0x1,
    
       [Display(Name = "Send Job Offers By Sms")]
       SendJobOffersBySms = 0x2,
    
       [Display(Name = "Send Other Stuff By Sms")]
       SendPromotionalBySms = 0x4,
    
       [Display(Name = "Send Other Stuff By Mail")]
       SendPromotionalByMail = 0x8
    }
    

    then if you want to create a dropdown selector you can use:

    @Html.EnumDropdownListFor(expression: model => model.PromotionSelector, optionLabel: "Select") 
    
    0 讨论(0)
提交回复
热议问题