我在我的模型中有一个属性叫做Promotion,它的类型是一个标志enum叫做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
}
现在我想要能够在我的视图中创建一个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>
基于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()而不是Name属性。这确保如果使用ResourceType属性,将返回本地化的字符串。
例子
要使用它,只需在视图中引用枚举值。
@{
UserPromotion promo = UserPromotion.SendJobOffersByMail;
}
Promotion: @promo.GetDisplayName()
输出
促销:通过邮件发送工作邀请
ASP。Net Core 3.0,这对我很有用(归功于之前的回答)。
我的Enum类:
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; }
}
显示标签和下拉列表的剃刀视图示例。注意下拉列表不需要helper方法:
@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>
}
假设你的枚举名称是OrderState,使用以下代码:
@Html.DropDownList("selectList", new SelectList(Html.GetEnumSelectList<OrderState>(), "Value", "Text",ViewBag.selectedOrderState), new {@id="OrderState", @class = "form-control" })
在后台设置选中的选项:
var selectedOrderState = ..Data.OrderState.GetHashCode();
ViewBag.selectedOrderState = selectedOrderState;
基于Todd的答案,建立在Aydin的答案之上,这是一个不需要任何类型参数的泛型扩展方法。
/// <summary>
/// Gets human-readable version of enum.
/// </summary>
/// <returns>effective DisplayAttribute.Name of given enum.</returns>
public static string GetDisplayName<T>(this T enumValue) where T : IComparable, IFormattable, IConvertible // C# 7.3+: where T : struct, Enum
{
if (!typeof(T).IsEnum) // Not needed in C# 7.3+ with above updated constraint
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();
}
我需要这个为我的项目,因为像下面的代码,其中不是每个成员的enum有一个DisplayAttribute,抛出一个异常与Todd的解决方案:
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
如果这是一个简单问题的复杂解决方案,请让我知道,但这是我使用的修复。
如果你使用的是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)