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

后端 未结 20 2389
孤街浪徒
孤街浪徒 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:47

    You could use Type.GetMember Method, then get the attribute info using reflection:

    // display attribute of "currentPromotion"
    
    var type = typeof(UserPromotion);
    var memberInfo = type.GetMember(currentPromotion.ToString());
    var attributes = memberInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);
    var description = ((DisplayAttribute)attributes[0]).Name;
    

    There were a few similar posts here:

    Getting attributes of Enum's value

    How to make MVC3 DisplayFor show the value of an Enum's Display-Attribute?

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

    2020 Update: An updated version of the function provided by many in this thread but now for C# 7.3 onwards:

    Now you can restrict generic methods to enums types so you can write a single method extension to use it with all your enums like this:

    The generic extension method:

    public static string ATexto<T>(this T enumeración) where T : struct, Enum {
        var tipo = enumeración.GetType();
        return tipo.GetMember(enumeración.ToString())
        .Where(x => x.MemberType == MemberTypes.Field && ((FieldInfo)x).FieldType == tipo).First()
        .GetCustomAttribute<DisplayAttribute>()?.Name ?? enumeración.ToString();
    } 
    

    The enum:

    public enum TipoImpuesto { 
    IVA, INC, [Display(Name = "IVA e INC")]IVAeINC, [Display(Name = "No aplica")]NoAplica };
    

    How to use it:

    var tipoImpuesto = TipoImpuesto.IVAeINC;
    var textoTipoImpuesto = tipoImpuesto.ATexto(); // Prints "IVA e INC".
    

    Bonus, Enums with Flags: If you are dealing with normal enums the function above is enough, but if any of your enums can take multiple values with the use of flags then you will need to modify it like this (This code uses C#8 features):

        public static string ATexto<T>(this T enumeración) where T : struct, Enum {
    
            var tipo = enumeración.GetType();
            var textoDirecto = enumeración.ToString();
    
            string obtenerTexto(string textoDirecto) => tipo.GetMember(textoDirecto)
                .Where(x => x.MemberType == MemberTypes.Field && ((FieldInfo)x).FieldType == tipo)
                .First().GetCustomAttribute<DisplayAttribute>()?.Name ?? textoDirecto;
    
            if (textoDirecto.Contains(", ")) {
    
                var texto = new StringBuilder();
                foreach (var textoDirectoAux in textoDirecto.Split(", ")) {
                    texto.Append($"{obtenerTexto(textoDirectoAux)}, ");
                }
                return texto.ToString()[0..^2];
    
            } else {
                return obtenerTexto(textoDirecto);
            }
    
        } 
    

    The enum with flags:

    [Flags] public enum TipoContribuyente {
        [Display(Name = "Común")] Común = 1, 
        [Display(Name = "Gran Contribuyente")] GranContribuyente = 2, 
        Autorretenedor = 4, 
        [Display(Name = "Retenedor de IVA")] RetenedorIVA = 8, 
        [Display(Name = "Régimen Simple")] RégimenSimple = 16 } 
    

    How to use it:

    var tipoContribuyente = TipoContribuyente.RetenedorIVA | TipoContribuyente.GranContribuyente;
    var textoAux = tipoContribuyente.ATexto(); // Prints "Gran Contribuyente, Retenedor de IVA".
    
    0 讨论(0)
  • 2020-11-22 09:48

    If you are using MVC 5.1 or upper there is simplier and clearer way: just use data annotation (from System.ComponentModel.DataAnnotations namespace) like below:

    public enum Color
    {
        [Display(Name = "Dark red")]
        DarkRed,
        [Display(Name = "Very dark red")]
        VeryDarkRed,
        [Display(Name = "Red or just black?")]
        ReallyDarkRed
    }
    

    And in view, just put it into proper html helper:

    @Html.EnumDropDownListFor(model => model.Color)
    
    0 讨论(0)
  • 2020-11-22 09:52
    <ul>
        @foreach (int aPromotion in @Enum.GetValues(typeof(UserPromotion)))
        {
            var currentPromotion = (int)Model.JobSeeker.Promotion;
            if ((currentPromotion & aPromotion) == aPromotion)
            {
            <li>@Html.DisplayFor(e => currentPromotion)</li>
            }
        }
    </ul>
    
    0 讨论(0)
  • 2020-11-22 09:52

    Building further on Aydin's and Todd's answers, here is an extension method that also lets you get the name from a resource file

    using AppResources;
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Reflection;
    using System.Resources;
    
    public static class EnumExtensions
    {
        public static string GetDisplayName(this Enum enumValue)
        {
            var enumMember= enumValue.GetType()
                            .GetMember(enumValue.ToString());
    
            DisplayAttribute displayAttrib = null;
            if (enumMember.Any()) {
                displayAttrib = enumMember 
                            .First()
                            .GetCustomAttribute<DisplayAttribute>();
            }
    
            string name = null;
            Type resource = null;
    
            if (displayAttrib != null)
            {
                name = displayAttrib.Name;
                resource = displayAttrib.ResourceType;
            }
    
            return String.IsNullOrEmpty(name) ? enumValue.ToString()
                : resource == null ?  name
                : new ResourceManager(resource).GetString(name);
        }
    }
    

    and use it like

    public enum Season 
    {
        [Display(ResourceType = typeof(Resource), Name = Season_Summer")]
        Summer
    }
    
    0 讨论(0)
  • 2020-11-22 09:54

    Based on Aydin's answer I would suggest a less "duplicatious" implementation (because we could easily get the Type from the Enum value itself, instead of providing it as a parameter

    0 讨论(0)
提交回复
热议问题