C# 如何通过 MVC 剃刀代码获取枚举成员的显示名称属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13099834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the Display Name Attribute of an Enum member via MVC razor code?
提问by Pejman
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:
我的模型中有一个名为“Promotion”的属性,它的类型是一个名为“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
}
Now I want to be able to create say a ul in my view to show the selected values of my "Promotion" property. This is what I have done so far but the problem is that how can I get the display names here?
现在我希望能够在我的视图中创建一个 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>
采纳答案by Hrvoje Stanisic
UPDATE
更新
First solution was focused on getting display names from enum. Code below should be exact solution for your problem.
第一个解决方案专注于从枚举中获取显示名称。下面的代码应该是您问题的确切解决方案。
You can use this helper class for enums:
您可以将此帮助类用于枚举:
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();
}
}
And then you can use it in your view as following:
然后您可以在您的视图中使用它,如下所示:
<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>
Hope it helps! :)
希望能帮助到你!:)
回答by alexn
You need to use a bit of reflection in order to access that attribute:
您需要使用一些反射才能访问该属性:
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;
I recommend wrapping this method in a extension method or perform this in a view model.
我建议将此方法包装在扩展方法中或在视图模型中执行此操作。
回答by Dmytro
<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>
回答by maximpa
You could use Type.GetMember Method, then get the attribute infousing reflection:
您可以使用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;
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?
回答by Aydin
One liner - Fluent syntax
一个班轮 - 流畅的语法
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>();
}
}
Example
例子
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);
}
}
Output
输出
Which season is it?
It's summer
现在是哪个季节?
夏天到了
回答by Todd
Building on Aydin's great answer, here's an extension method that doesn't require any type parameters.
基于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();
}
}
NOTE: GetName() should be used instead of the Name property. This ensures that the localized string will be returned if using the ResourceType attribute property.
注意:应该使用 GetName() 而不是 Name 属性。这确保如果使用 ResourceType 属性属性将返回本地化的字符串。
Example
例子
To use it, just reference the enum value in your view.
要使用它,只需在您的视图中引用枚举值。
@{
UserPromotion promo = UserPromotion.SendJobOffersByMail;
}
Promotion: @promo.GetDisplayName()
Output
输出
Promotion: Send Job Offers By Mail
促销:通过邮件发送工作机会
回答by Bernoulli IT
Based on Aydin's answerI would suggest a less "duplicatious" implementation (because we could easily get the Typefrom the Enumvalue itself, instead of providing it as a parameter :
基于Aydin 的回答,我建议采用一种不那么“重复”的实现(因为我们可以轻松地Type从Enum值本身获取 ,而不是将其作为参数提供:
public static string GetDisplayName(this Enum enumValue)
{
return enumValue.GetType().GetMember(enumValue.ToString())
.First()
.GetCustomAttribute<DisplayAttribute>()
.Name;
}
EDIT (based upon @Vahagn Nahapetyan's comment)
编辑(基于@Vahagn Nahapetyan 的评论)
public static string GetDisplayName(this Enum enumValue)
{
return enumValue.GetType()?
.GetMember(enumValue.ToString())?
.First()?
.GetCustomAttribute<DisplayAttribute>()?
.Name;
}
Now we can use it very clean in this way:
现在我们可以通过这种方式非常干净地使用它:
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();
Which results in
这导致
"The Dream"
“梦想”
回答by Peter Kerr
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
在 Aydin 和 Todd 的回答的基础上进一步构建,这里有一个扩展方法,它还可以让您从资源文件中获取名称
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
}
回答by 1_bug
If you are using MVC 5.1 or upper there is simplier and clearer way: just use data annotation (from System.ComponentModel.DataAnnotationsnamespace) like below:
如果您使用的是 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
}
And in view, just put it into proper html helper:
在视图中,只需将其放入适当的 html helper 中即可:
@Html.EnumDropDownListFor(model => model.Color)
回答by Kryszal
Based on previous answers I've created this comfortable helper to support all DisplayAttribute properties in a readable way:
基于以前的答案,我创建了这个舒适的助手,以可读的方式支持所有 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();
}
}

