MVC jilet kodu ile bir Enum üyesinin Görünen Ad Özniteliği nasıl edinilir?


211

Modelimde "UserPromotion" adlı bir bayrak numaralandırması olan "Promotion" adlı bir özelliğim var. Numaramın üyeleri aşağıdaki gibi ayarlanmış görüntüleme özelliklerine sahiptir:

[Flags]
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
}

Şimdi "Promosyon" özelliğinin seçilen değerlerini göstermek için benim görüşüme göre bir ul demek oluşturmak istiyorum. Şimdiye kadar yaptığım şey bu, ancak sorun şu ki, ekran adlarını buraya nasıl alabilirim?

<ul>
    @foreach (int aPromotion in @Enum.GetValues(typeof(UserPromotion)))
    {
        var currentPromotion = (int)Model.JobSeeker.Promotion;
        if ((currentPromotion & aPromotion) == aPromotion)
        {
        <li>Here I don't know how to get the display attribute of "currentPromotion".</li>
        }
    }
</ul>

12
MVC5, numaralandırmalarda DisplayName özniteliğini destekler.
Bart Calixto

10
Daha açık olmak gerekirse: Sadece System.ComponentModel.DataAnnotations.DisplayAttribute. Hayır System.ComponentModel.DisplayNameAttribute.
kamranicus

1
Bu, yansıma kullanımını içerir ve bu nedenle performansı etkiler mi? Çünkü buna çok zaman denecek.
Nico

Yanıtlar:


182

GÜNCELLEME

İlk çözüm, numaradan ekran adları almaya odaklandı. Aşağıdaki kod, sorununuz için kesin çözüm olmalıdır.

Bu yardımcı sınıfı, numaralandırmalar için kullanabilirsiniz:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;

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

Ve sonra görünümünde aşağıdaki gibi kullanabilirsiniz:

<ul>
    @foreach (var value in @EnumHelper<UserPromotion>.GetValues(UserPromotion.None))
    {
         if (value == Model.JobSeeker.Promotion)
        {
            var description = EnumHelper<UserPromotion>.GetDisplayValue(value);
            <li>@Html.DisplayFor(e => description )</li>
        }
    }
</ul>

Umarım yardımcı olur! :)


8
Tüm cevaplar kullanılır .ToString, ancak stackoverflow.com/q/483794/179311 adresinden , bunun Enum.GetNameyerine kullanıldığı söylenir.
bradlis7

GetField (value.ToString ()) tam olarak aradığım şeydi!
cdie

Bu cevap bazı eklenen null denetimleri ile iyidir, ancak dotfuscation kullanmıyorsanız stackoverflow.com/a/4412730/852806 adresindeki yanıt daha basit görünüyor.
HokeyJ

5
In GetDisplayValuesize ilk test etmelidir descriptionAttributes == nullEğer dizi erişmeye çalışmadan önce: descriptionAttributes[0]. Aksi takdirde bir istisna oluşturabilirsiniz ve null olup olmadığını kontrol ettiğiniz aşağıdaki satır asla doğru olmaz.
Robert S.

Küçük değişiklikler öneriyoruz: genel statik IList <T> GetValues ​​(Enum değeri) genel statik IList <T> GetValues ​​(T değeri) olabilir. EnumHelper <T> - => genel statik sınıf EnumHelper <T> burada T: struct, IConvertible. Belki statik yapıcı? static EnumHelper () {if (! typeof (T) .IsEnum) {yeni ArgumentException istisnası ("T numaralandırılmış tip olmalıdır"); }}
Tom

172

Bir astar - Akıcı sözdizimi

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

Misal

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

Çıktı

Hangi mevsim?
Yaz


2
GetCustomAttribute
Tito

3
@ Projenizin hedeflediğinden .NET Framework 4.5ve aşağıdaki ad alanlarını eklediğinizden emin olunSystem.Net System.ComponentModel.DataAnnotations
Aydın

8
System.Reflection kullanarak; System.ComponentModel.DataAnnotations kullanarak; Benim için gerekliydi.
Günahkar Lolwut

1
ne korkunç bir adlandırma kuralı!
curiousBoy

@curiousBoy GetAttribute<TAttribute>Korkunç bir adlandırma kuralı nasıl ? Belirttiğiniz özniteliği alır ve tüm genel yöntemlerde olduğu gibi pascal kasayı kullanır.
Aydın

137

Bina Aydın'ın büyük bir cevap , burada herhangi bir tür parametre gerektirmeyen bir uzantısı yöntemidir.

using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;

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

NOT: Name özelliği yerine GetName () kullanılmalıdır. Bu, ResourceType özniteliği özelliği kullanılırsa yerelleştirilmiş dizenin döndürülmesini sağlar.

Misal

Bunu kullanmak için, görünümünüzdeki numaralandırma değerine başvurmanız yeterlidir.

@{
    UserPromotion promo = UserPromotion.SendJobOffersByMail;
}

Promotion: @promo.GetDisplayName()

Çıktı

Promosyon: İş Tekliflerini Postayla Gönder


4
Aşağıdaki ad alanlarını eklemenin yanı sıra: using System; System.ComponentModel.DataAnnotations kullanarak; System.Linq kullanarak; System.Reflection kullanarak;
Peter Kerr

Kaygan bir çözüm, ancak {"Şablonlar yalnızca alan erişimi, özellik erişimi, tek boyutlu dizi dizini veya tek parametreli özel dizin oluşturucu ifadeleri ile kullanılabilir."}
Casey Crookston

Bu hata iletisi için diğer SO yanıtlarına baktığımda (buna aşina değilim), bunu bir Html yardımcı yönteminden (örneğin @Html.DisplayFor(m => m.myEnum.GetDisplayName()), işe yaramayacak, çünkü değerlendirilen ifadenin bir özellik vermesini beklediğinizden) kullanıyor olabileceğiniz anlaşılıyor. Yukarıdaki örnekte olduğu gibi çıplak numaralandırma değerini kullanmalısınız
Todd

7
GetCustomAttribute<DisplayAttribute>()Sonucu için bir boş başvuru denetimi ekledim, çünkü bazı Numaralandırmalar için bu mevcut olmayabilir. enumValue.ToString()DisplayAttribute öğesinin mevcut olmadığına geri döner .
H Dog

1
Bunu List<SelectListItem>tüm bireysel DisplayAttribute.Nameek açıklamalarla bir Enum tarafından doldurulmuş bir oluşturmak için kullandım - bu mükemmel çalıştı, teşekkür ederim !! public List<SelectListItem> MySelectListItem = new List<SelectListItem>(); foreach (MyEnum MyEnum in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Where(x => x != MyEnum.Default)) { MySelectListItem.Add(new SelectListItem() { Text = MyEnum.GetDisplayName(), Value = ((int)MyEnum).ToString() }); }
Hazne

61

Dayanarak Aydın'ın cevabı kolaylıkla alabilir çünkü (daha az "duplicatious" uygulanmasını öneririm Typedan Enumyerine bir parametre 😉 olarak sağlanması, değer kendisi:

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

EDIT (@Vahagn Nahapetyan'ın yorumuna dayanarak)

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

Şimdi bunu çok temiz bir şekilde kullanabiliriz:

public enum Season 
{
    [Display(Name = "The Autumn")]
    Autumn,

    [Display(Name = "The Weather")]
    Winter,

    [Display(Name = "The Tease")]
    Spring,

    [Display(Name = "The Dream")]
    Summer
}

Season.Summer.GetDisplayName();

Hangi sonuçlar

"Rüya"


1
Şimdiye kadar tüm cevapların en basit ve en kolayı. Teşekkürler!
Casey Crookston

.First () ile dikkatli olmalısınız. Örneğin, enum adınız "Eşittir" ise bir istisna oluşturur
Vahagn Nahapetyan

First () ile "tehlikeyi" anlıyorum. Bu özel durumda bir sorun gibi görünmüyor. Çünkü thisgeçerli (boş olmayan) bir Enum değeri olması gereken bir uzantı yöntemidir . Aksi takdirde, yöntemi çağırmak zaten atar (bu çağrı kodunun sorumluluğundadır). Bu, kesinlikle üye GetType()olacağı doğru Numaralandırma Türünü sağlar enumvalue. Ancak GetCustomAttribute bir null değeri döndürebilir, bu nedenle yöntem çağrıları zinciri bir yerde null dönüş değeri olduğunda null döndürmek için yöntemin olağanüstü olmayan bir sürümünü sağladım. Teşekkürler!
Bernoulli IT

1
Kodunuzun ikinci varyantı için, GetMember'den sonra null koşullu operatörün kullanılmasına gerek olmadığı anlaşılıyor çünkü bu yöntem her zaman bir MemberInfo dizisi döndürüyor ve hiçbir zaman null döndürmüyor. Ve benim için FirstOrDefault'u sadece First yerine kullanmak daha iyi görünüyor. Daha sonra FirstOrDefault'tan sonra null koşullu operatörün kullanılması tutarlı olarak görülecektir.
Alex34758

28

MVC 5.1 veya üstünü kullanıyorsanız, daha basit ve daha net bir yol vardır: sadece System.ComponentModel.DataAnnotationsaşağıdaki gibi veri ek açıklamalarını ( ad alanından) kullanın :

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

Ve görünümde, uygun html yardımcısına koyun:

@Html.EnumDropDownListFor(model => model.Color)

@SegmentationFault neden? Sorununuzu tarif edebilir misiniz? Hangi .NET / MVC sürümünü kullanıyorsunuz? Ne hatası var? Lütfen daha spesifik ol.
1_bug

6
Çünkü sadece Dropdowns için çalışıyor, başka hiçbir yerde değil.
Segmentasyon Hatası

2
.Net çekirdeğinde yok gibi görünüyor
Lonefish

3
Net çekirdek Html.GetEnumSelectList (typeof (YourEnum)) @Lonefish kullanır
Patrick Mcvay

2
@ Html.DisplayFor (yourEnumField) kullanmak istiyorsak, DisplayTemplates dizinine (paylaşılan dizinde) bir Enum.cshtml koyabiliriz. bu dosyaya sadece 2 satır koymamız gerekiyor. birincisi: "@model Enum" ikincisi: "@GetDisplayName (Model)." GetDisplayName yönteminin @Bernoulli IT answare
Developer'da

11

Type.GetMember Yöntemi'ni kullanabilir , ardından yansıma kullanarak öznitelik bilgilerini alabilirsiniz :

// 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;

Burada birkaç benzer gönderi vardı:

Enum'un değerinin niteliklerini alma

MVC3 DisplayFor bir Enum's Display-Attribute değerini göstermek için nasıl?


8

Bina Todd'un büyük bir cevap üzerine inşa Aydın'ın büyük bir cevap , burada var jenerik her türlü parametre gerektirmeyen uzatma yöntemi.

/// <summary>
/// Gets human-readable version of enum.
/// </summary>
/// <returns>DisplayAttribute.Name property of given enum.</returns>
public static string GetDisplayName<T>(this T enumValue) where T : IComparable, IFormattable, IConvertible
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("Argument must be of type Enum");

    DisplayAttribute displayAttribute = enumValue.GetType()
                                                 .GetMember(enumValue.ToString())
                                                 .First()
                                                 .GetCustomAttribute<DisplayAttribute>();

    string displayName = displayAttribute?.GetName();

    return displayName ?? enumValue.ToString();
}

Projem için buna ihtiyacım vardı, çünkü enumun her üyesinin sahip olmadığı aşağıdaki kod gibi bir şey DisplayAttributeTodd'un çözümü ile çalışmaz:

public class MyClass
{
    public enum MyEnum 
    {
        [Display(Name="ONE")]
        One,
        // No DisplayAttribute
        Two
    }
    public void UseMyEnum()
    {
        MyEnum foo = MyEnum.One;
        MyEnum bar = MyEnum.Two;
        Console.WriteLine(foo.GetDisplayName());
        Console.WriteLine(bar.GetDisplayName());
    }
}
// Output:
//
// ONE
// Two

Bu basit bir soruna karmaşık bir çözümse, lütfen bana bildirin, ancak kullandığım düzeltme buydu.


6
<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>

InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
Çalışmıyor

6

Bu soru için iki çözümüm var.

  1. İlk çözüm enum'dan görünen adları almaktır.
public enum CourseLocationTypes
{
    [Display(Name = "On Campus")]
    OnCampus,
    [Display(Name = "Online")]
    Online,
    [Display(Name = "Both")]
    Both
}

public static string DisplayName(this Enum value)
{
    Type enumType = value.GetType();
    string enumValue = Enum.GetName(enumType, value);
    MemberInfo member = enumType.GetMember(enumValue)[0];

    object[] attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
    string outString = ((DisplayAttribute)attrs[0]).Name;

    if (((DisplayAttribute)attrs[0]).ResourceType != null)
    {
        outString = ((DisplayAttribute)attrs[0]).GetName();
    }

    return outString;
}
<h3 class="product-title white">@Model.CourseLocationType.DisplayName()</h3>
  1. İkinci çözüm enum adından görünen adı almaktır, ancak bu yama adı geliştirici dilinde bölünmüş olacaktır.
public static string SplitOnCapitals(this string text)
{
        var r = new Regex(@"
            (?<=[A-Z])(?=[A-Z][a-z]) |
             (?<=[^A-Z])(?=[A-Z]) |
             (?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);

        return r.Replace(text, " ");
}
 <div class="widget-box pt-0">
     @foreach (var item in Enum.GetNames(typeof(CourseLocationType)))
     {
         <label class="pr-2 pt-1">
             @Html.RadioButtonFor(x => x.CourseLocationType, item, new { type = "radio", @class = "iCheckBox control-label" })&nbsp; @item.SplitOnCapitals()
         </label>
     }
     @Html.ValidationMessageFor(x => x.CourseLocationType)
 </div>

5

ASP.Net Core 3.0 için, bu benim için çalıştı (önceki yanıtlayanlara verilen kredi).

Enum sınıfım:

using System;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

public class Enums
{
    public enum Duration
    { 
        [Display(Name = "1 Hour")]
        OneHour,
        [Display(Name = "1 Day")]
        OneDay
    }

    // Helper method to display the name of the enum values.
    public static string GetDisplayName(Enum value)
    {
        return value.GetType()?
       .GetMember(value.ToString())?.First()?
       .GetCustomAttribute<DisplayAttribute>()?
       .Name;
    }
}

Görünüm Model Sınıfım:

public class MyViewModel
{
    public Duration Duration { get; set; }
}

Etiketi ve bir açılır listeyi gösteren ustura görünümü örneği. Açılır listenin yardımcı bir yöntem gerektirmediğine dikkat edin:

@model IEnumerable<MyViewModel> 

@foreach (var item in Model)
{
    <label asp-for="@item.Duration">@Enums.GetDisplayName(item.Duration)</label>
    <div class="form-group">
        <label asp-for="@item.Duration" class="control-label">Select Duration</label>
        <select asp-for="@item.Duration" class="form-control"
            asp-items="Html.GetEnumSelectList<Enums.Duration>()">
        </select>
    </div>
}

GetDisplayName yöntemi dönüş string.IsNullOrEmpty (retVal) üzerinde bir kontrol eklemek istiyorsunuz? enumValue.ToString (): retVal;
Sniipe

4

Bu özelliğe erişmek için biraz yansıma kullanmanız gerekir:

var type = typeof(UserPromotion);
var member = type.GetMember(Model.JobSeeker.Promotion.ToString());
var attributes = member[0].GetCustomAttributes(typeof(DisplayAttribute), false);
var name = ((DisplayAttribute)attributes[0]).Name;

Bu yöntemi bir uzantı yöntemine sarmanızı veya bir görünüm modelinde gerçekleştirmenizi öneririz.


4

Core 2.1 ile,

public static string GetDisplayName(Enum enumValue)
{
  return enumValue.GetType()?
 .GetMember(enumValue.ToString())?[0]?
 .GetCustomAttribute<DisplayAttribute>()?
 .Name;
}

4

tüm kenar kasalarını yukarıdan bir araya getirerek:

  • temel nesne üyelerinin adlarına sahip numaralandırma üyeleri ( Equals,ToString )
  • isteğe bağlı Displayözellik

İşte benim kod:

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

İsteğe bağlı Ekran özelliğini işleyen hoş bir çözüm. Teşekkürler!
Wellspring

3

Bunu yaptığım için özür dilerim, ama diğer cevapları olduğu gibi kullanamadım ve yorumlarda kullanmak için zamanım yoktu.

C # 6 sözdizimini kullanır.

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

2

Aydın'ın ve Todd'un cevaplarına daha fazla odaklanmak için, adı bir kaynak dosyasından almanızı sağlayan bir uzantı yöntemi

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

ve onu gibi kullan

public enum Season 
{
    [Display(ResourceType = typeof(Resource), Name = Season_Summer")]
    Summer
}

Projem için bu çalışmaya çalışıyorum ama "yeni ResourceManager (kaynak) .GetString (name);" ile ilgili bir hata alıyorum hat. Bir soru sordum ( stackoverflow.com/questions/31319251/… ) ve buraya gönderildim. Çalışırken "ResourceManager (kaynak)" görüntülediğimde "Resources.Enums.resource" döndürür. Herhangi bir yardım büyük mutluluk duyacağız. Teşekkür ederim!
Karinne

Bazı numaralandırma değerleri için Görünen Ad ayarlanmadığında null'ları daha iyi işlemek için kod güncellendi - yardımcı olabilir
Peter Kerr

Bu hala işe yaramadı. Stackoverflow.com/questions/31319251/… adresindeki sorumu hata mesajıyla güncelledim. Yardım için teşekkürler!
Karinne

1

Kültüre bağlı GetDisplayName enum uzantısı ile katkıda bulunmak istiyorum. Umarım bu cevabı daha önce benim gibi googling yapan herkes için yararlı olacaktır:

Aydın Adn ve Todd'un belirttiği gibi "standart" yol :

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

"Kültüre bağlı" yol:

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

1

2020 Güncelleştirmesi: Bu iş parçacığında birçok kişi tarafından sağlanan işlevin güncellenmiş bir sürümü ancak şimdi C # 7.3 için:

Artık genel yöntemleri numaralandırma türleriyle sınırlandırabilirsiniz, böylece bu gibi tüm numaralandırmalarınızla kullanmak için tek bir yöntem uzantısı yazabilirsiniz:

Genel genişletme yöntemi:

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

Numaralandırma:

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

Bu nasıl kullanılır:

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

Bonus, Bayraklı Numaralandırmalar: Normal numaralandırmalarla uğraşıyorsanız yukarıdaki işlev yeterlidir, ancak numaralandırmalarınızdan herhangi biri bayrakların kullanılmasıyla birden fazla değer alabilirse, bu şekilde değiştirmeniz gerekir (Bu kod C # 8 kullanır özellikleri):

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

    } 

Bayraklı numaralandırma:

[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 } 

Bu nasıl kullanılır:

var tipoContribuyente = TipoContribuyente.RetenedorIVA | TipoContribuyente.GranContribuyente;
var textoAux = tipoContribuyente.ATexto(); // Prints "Gran Contribuyente, Retenedor de IVA".

0

Önceki yanıtlara dayanarak, tüm DisplayAttribute özelliklerini okunabilir bir şekilde desteklemek için bu rahat yardımcıyı oluşturdum:

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

Bunu düzenleme olarak denedim ama reddedildi; Nedenini göremiyorum.

Yukarıdaki, özel özniteliklerle düz öğelerin bir karışımına sahip bir Enum ile çağırırsanız, örneğin bir istisna atar.

public enum CommentType
{
    All = 1,
    Rent = 2,
    Insurance = 3,
    [Display(Name="Service Charge")]
    ServiceCharge = 4
}

Bu nedenle, özel niteliklere erişmeye çalışmadan önce kodu çok az değiştirdim ve hiçbiri bulunmazsa adı kullanın.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;

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

0

MVC5 kullanarak şunları kullanabilirsiniz:

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
}

bir açılır liste oluşturmak istiyorsanız şunları kullanabilirsiniz:

@Html.EnumDropdownListFor(expression: model => model.PromotionSelector, optionLabel: "Select") 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.