以下稍后更新
我正在尝试将[Description]
数据注释属性与enums
一起使用,以显示友好名称。我经常搜索很多东西,无法实现任何目标。现在我的代码将enum
显示为字符串(使用扩展名),但我不喜欢ThisIsAnEnum
作为enum
名称(由字符串扩展名分隔)并禁止我使用更长的名称(我需要维护),例如单选按钮项目。我的目标是对单选按钮项进行更长的描述,而不必编写真正长的枚举。扩展/帮助可能是正确的方法,但我需要"适合"它进入我正在使用的代码中,这是我在那里使用许多示例失败的地方。
我使用的代码是通用的,因为根据某些逻辑,显示单选按钮列表,复选框列表,下拉列表,选择列表或常规文本框。对于多项目列表,使用enum
,enum
名称显示(使用字符串扩展名后)。
以下是显示枚举的特定代码:
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>
(T selectedValue = default(T)) where T : struct
{
return from name in Enum.GetNames(typeof(T))
let enumValue = Convert.ToString((T)Enum.Parse(typeof(T), name, true))
select new SelectListItem
{
Text = name.ProperCase(),
Value = enumValue,
Selected = enumValue.Equals(selectedValue)
};
}
ProperCase
是将enum
更改为可读内容的类。
我找到了几乎有用的东西:
public static string GetEnumDescription<TEnum>(TEnum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if ((attributes != null) && (attributes.Length > 0))
return attributes[0].Description;
else
return value.ToString();
}
在这种情况下,我将代码从Text = name.ProperCase(),
更改为Text = name.GetEnumDescription(...)
,但如果我将value
放在括号中,我会得到一个&#34;在当前上下文中不存在&#34;消息(我尝试修复但只是让问题变得更糟)。如果我把它留空,我会得到&#34;没有超载......需要0个参数&#34; (再次,可以理解 - 但我不知道如何解决)。如果我将name
放在括号中,代码会编译,但在查看页面时,我会得到&#34;对象引用未设置...&#34;这一行出错:
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes
(typeof(DescriptionAttribute), false);
我花了很多时间在这上面,知道我的绊脚石是
Text = name.ProperCase(),
代码。任何想法/帮助?提前谢谢。
更新
如果我这样做:
Text = GetEnumDescription(selectedValue),
我实际上得到[Description]
文本,但是,它只显示第一个枚举。因此,如果我有5个枚举,但所有[Description]
代码都不同,则代码只会为第一个枚举重复[Description]
5次而不是为每个枚举显示不同的内容。我希望这有意义并缩小问题范围。
答案 0 :(得分:2)
我建议您使用Display
属性:
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>(T selectedValue = default(T)) where T : struct
{
return
from name in Enum.GetNames(typeof(T))
let enumValue = Convert.ToString((T)Enum.Parse(typeof(T), name, true))
select new SelectListItem
{
Text = GetEnumDescription(name, typeof(T)),
Value = enumValue,
Selected = name == selectedValue.ToString()
};
}
public static string GetEnumDescription(string value, Type enumType)
{
var fi = enumType.GetField(value.ToString());
var display = fi
.GetCustomAttributes(typeof(DisplayAttribute), false)
.OfType<DisplayAttribute>()
.FirstOrDefault();
if (display != null)
{
return display.Name;
}
return value;
}
然后你可以:
public enum Foo
{
[Display(Name = "value 1")]
Value1,
Value2,
[Display(Name = "value 3")]
Value3
}
现在你可以:
var foo = Foo.Value2;
var values = GetItemsFromEnum(foo);
另请注意,我修改了LINQ表达式中的Selected
子句,因为它不正确。
话虽如此,我个人建议你远离视图模型上的枚举,因为它们不能很好地与内置的ASP.NET MVC一起使用,你将不得不重新发明大部分内容。