如何通过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(); } }