如何通过MVCrazor代码获得一个枚举成员的显示名称属性?

我在我的模型中有一个名为“Promotion”的属性,它的types是一个名为“UserPromotion”的标志枚举。 我的枚举成员显示属性设置如下:

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

现在我想能够在我的视图中创build一个ul来显示我的“Promotion”属性的选定值。 这是我迄今为止所做的,但问题是,我怎样才能在这里获得显示名称?

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

UPDATE

第一个解决scheme的重点是从枚举中获取显示名称。 下面的代码应该是你的问题的确切解决scheme。

你可以使用这个辅助类的枚举:

 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> 

希望能帮助到你! 🙂

一个class轮 – stream利的语法

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

产量

哪个季节?
夏天到了

build立在艾登的伟大的答案 ,这是一个扩展方法,不需要任何types的参数。

 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()而不是Name属性。 这确保了如果使用ResourceType属性属性将返回本地化的string。

要使用它,只需在您的视图中引用枚举值。

 @{ UserPromotion promo = UserPromotion.SendJobOffersByMail; } Promotion: @promo.GetDisplayName() 

产量

促销:通过邮件发送工作机会

基于艾登的答案,我会build议一个不太“重复”的实现(因为我们可以很容易地从Enum值本身获取Type ,而不是将其作为参数提供):

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

哪个结果

“梦想”

如果你使用的是MVC 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 helper中即可:

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

您可以使用Type.GetMember方法 ,然后使用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; 

这里有几个类似的post:

获取Enum的值的属性

如何使MVC3 DisplayFor显示枚举的显示属性的值?

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

您需要使用一点reflection才能访问该属性:

 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; 

我build议在扩展方法中包装这个方法,或者在视图模型中执行这个方法。

我很抱歉这样做,但是我现在还不能使用任何其他答案,也没有时间在评论中使用。

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

进一步build立艾登和托德的答案,这里是一个扩展方法,也可以让你从资源文件的名称

 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 } 

build立在艾德的伟大答案基础上的托德的伟大 的答案 ,这里是一个通用的扩展方法,不需要任何types的参数。

 /// <summary> /// Get human-readable version of enum /// </summary> /// <returns>DisplayAttribute.Name field 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"); try { return enumValue.GetType() // GetType causes exception if DisplayAttribute.Name is not set .GetMember(enumValue.ToString()) .First() .GetCustomAttribute<DisplayAttribute>() .GetName(); } catch // If there's no DisplayAttribute.Name set, just return the ToString value { return enumValue.ToString(); } } 

我需要这个为我的项目,因为像下面的代码不能用Todd的解决scheme:

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

如果这是一个简单问题的复杂解决scheme,请让我知道,但这是我使用的修复。

根据以前的答案,我已经创build了这个舒适的帮助器,以可读的方式支持所有的DisplayAttribute属性:

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