MVC रेजर कोड के माध्यम से एक एनम सदस्य का प्रदर्शन नाम विशेषता कैसे प्राप्त करें?


211

मुझे अपने मॉडल में "प्रमोशन" नाम की एक प्रॉपर्टी मिली है कि इसका प्रकार एक फ्लैग एनम है जिसे "यूजरप्रोमिशन" कहा जाता है। मेरे एनम के सदस्यों में निम्न प्रकार के प्रदर्शन गुण हैं:

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

अब मैं अपनी "प्रमोशन" संपत्ति के चयनित मूल्यों को दिखाने के लिए मेरे विचार में एक उल कहने में सक्षम होना चाहता हूं। यह वही है जो मैंने अभी तक किया है, लेकिन समस्या यह है कि मैं यहां प्रदर्शन नाम कैसे प्राप्त कर सकता हूं?

<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 enums पर DisplayName विशेषता का समर्थन करता है।
बार्ट कैलिक्सो

10
स्पष्ट होने के लिए: केवल System.ComponentModel.DataAnnotations.DisplayAttribute। नहीं है System.ComponentModel.DisplayNameAttribute
कामरानिकस

1
क्या इसमें प्रतिबिंब का उपयोग शामिल है और इसलिए प्रदर्शन को प्रभावित करता है? 'क्योंकि यह बहुत समय कहा जाता है।
निको

जवाबों:


182

अपडेट करें

पहला समाधान एनम से प्रदर्शन नाम प्राप्त करने पर केंद्रित था। नीचे दिया गया कोड आपकी समस्या का सटीक समाधान होना चाहिए।

आप इस सहायक श्रेणी का उपयोग कर सकते हैं:

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

और फिर आप इसे अपने विचार में निम्नानुसार उपयोग कर सकते हैं:

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

आशा करता हूँ की ये काम करेगा! :)


8
सभी उत्तर का उपयोग करते हैं .ToString, लेकिन stackoverflow.com/q/483794/179311 से , इसके Enum.GetNameबजाय इसका उपयोग करने के लिए कहते हैं ।
bradlis7

value.GetType ()। GetField (value.ToString ()) वास्तव में मैं क्या देख रहा था!
cdie

यह उत्तर कुछ अतिरिक्त अशक्त जाँच के साथ ठीक है, लेकिन यदि आप dotfuscation का उपयोग stackoverflow.com/a/4412730/852806 पर नहीं कर रहे हैं तो यह सरल प्रतीत होता है।
हॉकी फेज

5
में GetDisplayValueआप पहली बार परीक्षण करना चाहिए descriptionAttributes == nullआप सरणी तक पहुँचने का प्रयास करने से पहले: descriptionAttributes[0]। अन्यथा आप एक अपवाद बढ़ा सकते हैं और नीचे की रेखा जहां आप शून्य की जांच करते हैं, वह कभी सच नहीं होगा।
रॉबर्ट एस।

मैं नाबालिगों के बदलाव का सुझाव दूंगा: सार्वजनिक स्थैतिक IList <T> GetValues ​​(Enum value) सार्वजनिक स्थैतिक IList <T> GetValues ​​(T मान) हो सकता है। EnumHelper <T> से => सार्वजनिक स्थैतिक वर्ग EnumHelper <T> जहां T: संरचना, IConvertible। शायद स्थिर अवरोधक? स्थिर EnumHelper () {if ((टाइपोफ़ (T) .IsEnum)) {नया ArgumentException फेंकें ("T एक एनुमरेटेड टाइप होना चाहिए"); }}
टॉम

172

एक लाइनर - धाराप्रवाह वाक्य रचना

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

उदाहरण

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

उत्पादन

कौन सी ऋतु है?
यह गर्मी है


2
GetCustomAttribute
Tito

3
@ यह सुनिश्चित करें कि आपकी परियोजना लक्षित है .NET Framework 4.5और आप निम्नलिखित नामस्थानों में शामिल हैंSystem.Net System.ComponentModel.DataAnnotations
Aydin

8
System.Reflection का उपयोग करना; System.ComponentModel.DataAnnotations का उपयोग करना; मेरे लिए जरूरी था।
पापपूर्ण लोलवुत

1
क्या एक भयानक नामकरण सम्मेलन!
उत्सुकताजनक

@curiousBoy GetAttribute<TAttribute>एक भयानक नामकरण सम्मेलन कैसे है ? यह आपके द्वारा निर्दिष्ट विशेषता को पुनः प्राप्त करता है और पास्कल आवरण का उपयोग करता है जैसा कि सभी सार्वजनिक तरीकों को करना चाहिए।
Aydin

137

Aydin के महान जवाब पर निर्माण , यहाँ एक विस्तार विधि है जिसमें किसी भी प्रकार के मापदंडों की आवश्यकता नहीं होती है।

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

नोट: GetName () का उपयोग नाम संपत्ति के बजाय किया जाना चाहिए। यह सुनिश्चित करता है कि यदि संसाधनटाइप विशेषता गुण का उपयोग करके स्थानीय स्ट्रिंग वापस कर दी जाएगी।

उदाहरण

इसका उपयोग करने के लिए, बस अपने विचार में enum मान को देखें।

@{
    UserPromotion promo = UserPromotion.SendJobOffersByMail;
}

Promotion: @promo.GetDisplayName()

उत्पादन

पदोन्नति: मेल द्वारा नौकरी के प्रस्ताव भेजें


4
निम्नलिखित नामस्थानों को जोड़ने का प्रयास करें: सिस्टम का उपयोग करना; System.ComponentModel.DataAnnotations का उपयोग करना; System.Linq का उपयोग करना; System.Reflection का उपयोग करना;
पीटर केर

चालाक समाधान, लेकिन मुझे {"टेम्पलेट का उपयोग केवल फ़ील्ड एक्सेस, प्रॉपर्टी एक्सेस, सिंगल-डायमेंशन एरे इंडेक्स या सिंगल-पैरामीटर कस्टम इंडेक्सर एक्सप्रेशंस के साथ किया जा सकता है।"}
केसी क्रुकस्टन

इस त्रुटि संदेश के लिए अन्य SO उत्तरों को देखते हुए (मैं इससे अपरिचित हूं), ऐसा प्रतीत होता है कि आप इसका उपयोग एचटीएमएल हेल्पर विधि (जैसे @Html.DisplayFor(m => m.myEnum.GetDisplayName()), जो काम नहीं करेंगे, क्योंकि वे एक संपत्ति प्राप्त करने के लिए मूल्यांकन किए गए अभिव्यक्ति की उम्मीद करते हैं, से कर सकते हैं) या कुछ इसी तरह। आपको ऊपर दिए उदाहरण में नंगे एनुम मूल्य का उपयोग करना चाहिए।
टॉड

7
मैंने परिणाम के लिए एक अशक्त संदर्भ जांच जोड़ी GetCustomAttribute<DisplayAttribute>()क्योंकि कुछ Enums के लिए शायद यह मौजूद नहीं है। यह प्रदर्शित होता है enumValue.ToString()अगर DisplayAttribute मौजूद नहीं था।
एच डॉग

1
मैंने इसका इस्तेमाल List<SelectListItem>एक एनम द्वारा सभी व्यक्तिगत DisplayAttribute.Nameएनोटेशन के साथ आबाद करने के लिए किया था - यह पूरी तरह से काम करता है, धन्यवाद !! 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() }); }
हूपर

61

Aydin के जवाब के आधार पर मैं एक कम "डुप्लिकेट" कार्यान्वयन का सुझाव दूंगा (क्योंकि हम आसानी Typeसे Enumमान से ही प्राप्त कर सकते हैं , बजाय इसे एक पैरामीटर के रूप में प्रदान करने के लिए's:

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

EDIT (@Vahagn Nahapetyan की टिप्पणी पर आधारित)

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

अब हम इसे इस तरह से साफ कर सकते हैं:

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

जिसके परिणामस्वरूप

"सपना"


1
अब तक सभी उत्तरों में से सबसे सरल और सबसे आसान। धन्यवाद!
केसी क्रुकस्टन

तुम। के साथ सावधान रहना चाहिए ()। यह उदाहरण के लिए एक अपवाद को फेंक देगा यदि आपका
एनम

मैं पहले () के साथ "खतरे" को समझता हूं। इस विशेष मामले में यह एक मुद्दा नहीं लगता है। क्योंकि यह एक विस्तार विधि है जहां thisएक वैध होना चाहिए (शून्य नहीं) एनम मान। अन्यथा कॉलिंग विधि पहले से ही फेंक देगी (जो कॉलिंग कोड की जिम्मेदारी है)। यह GetType()सुनिश्चित करता है कि सही Enum प्रकार प्रदान enumvalueकरेगा जिसमें सुनिश्चित करने के लिए एक सदस्य होगा। लेकिन GetCustomAttribute एक अशक्त मान लौटा सकता है इसलिए मैंने अशक्त वापस आने के लिए विधि का एक गैर-असाधारण संस्करण प्रदान किया जब विधि कॉलों की श्रृंखला में एक अशक्त वापसी मान होता है। धन्यवाद!
बर्नौली आईटी

1
आपके कोड के दूसरे संस्करण के लिए, ऐसा लगता है कि GetMember के बाद अशक्त-संचालक ऑपरेटर का उपयोग करने की कोई आवश्यकता नहीं है क्योंकि यह विधि हमेशा सदस्यइन्फो की एक सरणी लौटाती है और कभी भी अशक्त नहीं लौटती है। और मेरे लिए ऐसा लगता है कि सिर्फ First की जगह FirstOrDefault का उपयोग करना बेहतर है। तब FirstOrDefault के बाद null-सशर्त ऑपरेटर का उपयोग लगातार देखा जाएगा।
एलेक्स 34758

28

यदि आप एमवीसी 5.1 या ऊपरी का उपयोग कर रहे हैं तो सरल और स्पष्ट तरीका है: बस डेटा एनोटेशन का उपयोग करें ( System.ComponentModel.DataAnnotationsजैसे नामस्थान से) जैसे:

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

और देखने में, इसे उचित HTML सहायक में रखें:

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

@ सिचुएशनफॉल्ट क्यों? क्या आप अपनी समस्या का वर्णन कर सकते हैं? आप .NET / MVC के किस संस्करण का उपयोग करते हैं? आपको क्या त्रुटि हुई है? कृपया और स्पष्ट बताएं।
1_बग

6
क्योंकि यह केवल Dropdowns के लिए काम करता है, कहीं और नहीं।
खंडन दोष

2
.Net

3
.net कोर Html.GetEnumSelectList (typeof (YourEnum)) @Lonefish
पैट्रिक मैकवे

2
अगर हम @ Html.DisplayFor (yourEnumField) का उपयोग करना चाहते हैं तो हम DisplayTemplates निर्देशिका (साझा निर्देशिका में) में Enum.cshtml डाल सकते हैं। इस फाइल में हमें सिर्फ 2 लाइनें डालने की जरूरत है। पहला है: "@ ममॉडल एनम" दूसरा है: "@GetDisplayName (मॉडल)।" GetDisplayName विधि @Bernoulli IT answare के रूप में होने की आवश्यकता है
डेवलपर

11

आप Type.GetMember Method का उपयोग कर सकते हैं , फिर प्रतिबिंब का उपयोग करके विशेषता जानकारी प्राप्त करें :

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

यहाँ कुछ समान पोस्ट थे:

एनुम के मूल्य के गुण प्राप्त करना

MVC3 DisplayFor को एनम के डिस्प्ले-एट्रीब्यूट का मान कैसे दिखाया जाए?


8

पर बिल्डिंग टोड के महान जवाब जो पर बनाया गया Aydin के महान जवाब , यहाँ एक है सामान्य विस्तार विधि है कि किसी भी प्रकार के मानकों की आवश्यकता नहीं है।

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

मुझे अपनी परियोजना के लिए इसकी आवश्यकता थी क्योंकि नीचे दिए गए कोड की तरह कुछ, जहां एनम के प्रत्येक सदस्य के पास DisplayAttributeनहीं है, टोड के समाधान के साथ काम नहीं करता है:

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

यदि यह एक सरल समस्या का एक जटिल समाधान है, तो कृपया मुझे बताएं, लेकिन यह वह फिक्स था जिसका मैंने उपयोग किया था।


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.
मुफ्लिक्स

6

मेरे पास इस प्रश्न के दो समाधान हैं।

  1. पहला समाधान एनम से प्रदर्शन नाम प्राप्त करने पर है।
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. दूसरा सॉल्यूशन एनुम नाम से डिस्प्ले नाम पाने पर है, लेकिन इसे डेवलपर भाषा में एनुम स्प्लिट किया जाएगा जिसे पैच कहा जाता है।
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 कोर 3.0 के लिए, इसने मेरे लिए काम किया (पिछले उत्तरदाताओं के लिए)।

मेरी एनम वर्ग:

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

मेरा दृश्य मॉडल वर्ग:

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

एक रेजर दृश्य का एक उदाहरण जो एक लेबल और एक ड्रॉप-डाउन सूची प्रदर्शित करता है। सूचना ड्रॉप-डाउन सूची में सहायक विधि की आवश्यकता नहीं है:

@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 विधि वापसी स्ट्रिंग पर एक चेक जोड़ूंगा। SsNullOrEmpty (retVal)? enumValue.ToString (): retVal;
स्निएप

4

उस विशेषता तक पहुंचने के लिए आपको थोड़ा सा प्रतिबिंब का उपयोग करने की आवश्यकता है:

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;

मैं इस पद्धति को एक विस्तार विधि में लपेटने की सलाह देता हूं या एक दृश्य मॉडल में यह प्रदर्शन करता हूं।


4

कोर 2.1 के साथ,

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

4

ऊपर से सभी किनारे-मामलों को एक साथ मिलाकर:

  • आधार ऑब्जेक्ट सदस्यों के नाम ( Equals, ToString) के साथ enum सदस्य
  • वैकल्पिक Displayविशेषता

यहाँ मेरा कोड है:

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

अच्छा समाधान जो वैकल्पिक प्रदर्शन विशेषता को संभालता है। धन्यवाद!
सोता

3

मुझे यह करने के लिए खेद है, लेकिन मैं अन्य उत्तरों में से किसी का भी उपयोग नहीं कर सका-और इसे टिप्पणियों में बाहर करने का समय नहीं है।

C # 6 सिंटैक्स का उपयोग करता है।

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

आयडिन और टॉड के उत्तरों पर आगे बढ़ते हुए, यहां एक विस्तार पद्धति है जो आपको संसाधन फ़ाइल से नाम प्राप्त करने की सुविधा भी देती है

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

और इसका उपयोग करें

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

मैं अपने प्रोजेक्ट के लिए यह काम करने की कोशिश कर रहा हूं, लेकिन मुझे "नए संसाधन प्रबंधक (संसाधन) .GetString (नाम) के साथ एक त्रुटि मिली है;" लाइन। मैंने एक प्रश्न पूछा था ( stackoverflow.com/questions/31319251/… ) और मुझे यहाँ भेजा गया था। जब मैं "रिसोर्स मैनजर (संसाधन)" देखता हूं, तो इसे "रिसोर्स.इन्मस.स्रोस" देता है। किसी भी तरह की सहायता का स्वागत किया जाएगा। धन्यवाद!
करिन्ने जूल 9'15

बेहतर एन्यूल्स को संभालने के लिए कोड को अपडेट करें जब आपके पास कुछ एनम वैल्यू के लिए डिस्प्ले नेम सेट न हो
पीटर केर

वह अभी भी काम नहीं किया। मैंने त्रुटि संदेश के साथ stackoverflow.com/questions/31319251/… पर अपना प्रश्न अपडेट किया । सहायता के लिए धन्यवाद!
करिने

1

मैं संस्कृति पर निर्भर GetDisplayName एनम एक्सटेंशन के साथ योगदान करना चाहता हूं। आशा है कि यह मेरे जैसे पहले वाले इस जवाब को गुमराह करने वाले के लिए उपयोगी होगा:

Aydin Adn और टोड के रूप में "standart" रास्ता :

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

"संस्कृति-निर्भर" तरीका:

    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 अद्यतन: इस धागे में कई द्वारा प्रदान किए गए फ़ंक्शन का एक अद्यतन संस्करण लेकिन अब C # 7.3 के लिए आगे:

अब आप जेनेरिक विधियों को एनम के प्रकारों तक सीमित कर सकते हैं ताकि आप इस तरह से अपने सभी एनम के साथ इसका उपयोग करने के लिए एक एकल विधि एक्सटेंशन लिख सकें:

सामान्य विस्तार विधि:

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

एनम:

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

इसे कैसे उपयोग करे:

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

बोनस, एनगैस विद फ़्लैग: यदि आप सामान्य एनम से निपट रहे हैं, तो उपरोक्त फ़ंक्शन पर्याप्त है, लेकिन यदि आपका कोई भी एंथम झंडे के उपयोग के साथ कई मान ले सकता है, तो आपको इसे इस तरह संशोधित करना होगा (यह कोड C # 8 का उपयोग करता है विशेषताएं):

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

    } 

झंडे के साथ एनम:

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

इसे कैसे उपयोग करे:

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

0

पिछले जवाबों के आधार पर, मैंने सभी डिस्प्लेएट्रिब्यूट गुणों को पढ़ने योग्य तरीके से समर्थन करने के लिए यह आरामदायक सहायक बनाया है:

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

मैंने इसे एक संपादन के रूप में करने की कोशिश की लेकिन इसे अस्वीकार कर दिया गया; मैं क्यों नहीं देख सकता।

यदि आप एक एंम के साथ कॉल करते हैं, तो कस्टम अपवाद और सादे वस्तुओं का मिश्रण होता है, उदाहरण के लिए, एक अपवाद को फेंक देगा

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

इसलिए मैंने उन्हें एक्सेस करने की कोशिश करने से पहले कस्टम विशेषताओं के लिए जाँच करने के लिए कोड को कभी-कभी थोड़ा संशोधित किया है, और यदि कोई नहीं मिला तो नाम का उपयोग करें।

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 का उपयोग करके आप उपयोग कर सकते हैं:

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
}

फिर यदि आप एक ड्रॉपडाउन चयनकर्ता बनाना चाहते हैं, जिसका आप उपयोग कर सकते हैं:

@Html.EnumDropdownListFor(expression: model => model.PromotionSelector, optionLabel: "Select") 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.