asp.net-mvc MVC.net 在视图中获取枚举显示名称,而无需在视图中引用枚举类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9328972/
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
MVC.net get enum display name in view without having to refer to enum type in view
提问by nathfy
I have the following helper method in a ViewModelBaseclass, which is inherited by other view Models:
我在一个ViewModelBase类中有以下辅助方法,该方法由其他视图模型继承:
public string GetEnumName<T>(Enum value)
{
Type enumType = typeof(T);
var enumValue = Enum.GetName(enumType, value);
MemberInfo member = enumType.GetMember(enumValue)[0];
var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
var outString = ((DisplayAttribute)attrs[0]).Name;
if (((DisplayAttribute)attrs[0]).ResourceType != null)
{
outString = ((DisplayAttribute)attrs[0]).GetName();
}
return outString;
}
I then call this from the view like this:
然后我从这样的视图中调用它:
<p>
@{var rel = Model.GetEnumDisplayName<Enums.wheteverEnum>(Model.wheteverEnum); }
@rel
</p>
Question is - can I work this method so I don't have to tell it the type of the enum? Basically I'd like todo this for all enums:
问题是 - 我可以使用这种方法,所以我不必告诉它 的类型enum吗?基本上我想为所有enum的人做到这一点:
@Model.GetEnumDisplayName(Model.wheteverEnum)
@Model.GetEnumDisplayName(Model.wheteverEnum)
No typeof, no T, no need to add a reference to the Enumsnamespace in the View...
不typeof,不T,不需要Enums在视图中添加对命名空间的引用...
Possible?
可能的?
回答by jrummell
You can simply remove the type parameter and make it an extension method.
您可以简单地删除类型参数并使其成为扩展方法。
public static string DisplayName(this Enum value)
{
Type enumType = value.GetType();
var enumValue = Enum.GetName(enumType, value);
MemberInfo member = enumType.GetMember(enumValue)[0];
var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
var outString = ((DisplayAttribute)attrs[0]).Name;
if (((DisplayAttribute)attrs[0]).ResourceType != null)
{
outString = ((DisplayAttribute)attrs[0]).GetName();
}
return outString;
}
@Model.wheteverEnum.DisplayName()
回答by devdigital
Could you not write this as an extension method? Something like...
你不能把它写成一个扩展方法吗?就像是...
public static class EnumExtensions
{
public static string ToDescription(this Enum e)
{
var attributes = (DisplayAttribute[])e.GetType().GetField(e.ToString()).GetCustomAttributes(typeof(DisplayAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : string.Empty;
}
}
Usage:
用法:
@Model.WhateverEnum.ToDescription();
回答by toepoke.co.uk
Nice work @jrummell!
干得好@jrummell!
I've added a small tweak below which captures the scenario where an enum doesn't have an associated Displayattribute (currently it throws an exception)
我在下面添加了一个小调整,它捕获了枚举没有关联的Display属性的场景(当前它抛出异常)
/// <summary>
/// Gets the DataAnnotation DisplayName attribute for a given enum (for displaying enums values nicely to users)
/// </summary>
/// <param name="value">Enum value to get display for</param>
/// <returns>Pretty version of enum (if there is one)</returns>
/// <remarks>
/// Inspired by :
/// http://stackoverflow.com/questions/9328972/mvc-net-get-enum-display-name-in-view-without-having-to-refer-to-enum-type-in-vi
/// </remarks>
public static string DisplayFor(this Enum value) {
Type enumType = value.GetType();
var enumValue = Enum.GetName(enumType, value);
MemberInfo member = enumType.GetMember(enumValue)[0];
string outString = "";
var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
if (attrs.Any()) {
var displayAttr = ((DisplayAttribute)attrs[0]);
outString = displayAttr.Name;
if (displayAttr.ResourceType != null) {
outString = displayAttr.GetName();
}
} else {
outString = value.ToString();
}
return outString;
}
回答by Pierre Watelet
The answer of @jrummell in VB.NET for the few of us...
@jrummell 在 VB.NET 中为我们几个人的答案...
Module ModuleExtension
<Extension()>
Public Function DisplayName(ByVal value As System.Enum) As String
Dim enumType As Type = value.GetType()
Dim enumValue = System.Enum.GetName(enumType, value)
Dim member As MemberInfo = enumType.GetMember(enumValue)(0)
Dim attrs = member.GetCustomAttributes(GetType(DisplayAttribute), False)
Dim outString = CType(attrs(0), DisplayAttribute).Name
If (CType(attrs(0), DisplayAttribute).ResourceType IsNot Nothing) Then
outString = CType(attrs(0), DisplayAttribute).GetName()
End If
Return outString
End Function
End Module
回答by Muhannad Al-Khodari
for anyone who might reach to this question, I found this a lot easier than any thing else: https://www.codeproject.com/articles/776908/dealing-with-enum-in-mvc
对于任何可能回答这个问题的人,我发现这比其他任何事情都容易得多:https: //www.codeproject.com/articles/776908/dealing-with-enum-in-mvc
Just create a folder "DisplayTemplate" under "Views\Shared", and create an empty view (Name it "Enum") in the new folder "DisplayTemplate", and copy this code to it"
只需在“Views\Shared”下创建一个文件夹“DisplayTemplate”,并在新文件夹“DisplayTemplate”中创建一个空视图(将其命名为“Enum”),并将此代码复制到其中”
@model Enum
@if (EnumHelper.IsValidForEnumHelper(ViewData.ModelMetadata))
{
// Display Enum using same names (from [Display] attributes) as in editors
string displayName = null;
foreach (SelectListItem item in EnumHelper.GetSelectList(ViewData.ModelMetadata, (Enum)Model))
{
if (item.Selected)
{
displayName = item.Text ?? item.Value;
}
}
// Handle the unexpected case that nothing is selected
if (String.IsNullOrEmpty(displayName))
{
if (Model == null)
{
displayName = String.Empty;
}
else
{
displayName = Model.ToString();
}
}
@Html.DisplayTextFor(model => displayName)
}
else
{
// This Enum type is not supported. Fall back to the text.
@Html.DisplayTextFor(model => model)
}
回答by Anis Saddoud
The suggested sollutions does not worked for me with MVC3: so the helper below is good.:
建议的解决方案在 MVC3 中对我不起作用:所以下面的帮助程序很好。:
public static string GetEnumDescription(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name != null)
{
FieldInfo field = type.GetField(name);
if (field != null)
{
string attr = field.GetCustomAttributesData()[0].NamedArguments[0].TypedValue.Value.ToString();
if (attr == null)
{
return name;
}
else
{
return attr;
}
}
}
return null;
}
回答by Anthony Shaw
Here is an extension method that I've written to do just this... it has a little extra logic in it to parse Enum names and split by capital letters. You can override any name by using the Display Attribute
这是我编写的一个扩展方法,用于执行此操作......它有一些额外的逻辑来解析枚举名称并按大写字母拆分。您可以使用显示属性覆盖任何名称
public static TAttribute GetAttribute<TAttribute>(this ICustomAttributeProvider parameterInfo) where TAttribute : Attribute
{
object[] attributes = parameterInfo.GetCustomAttributes(typeof(TAttribute), false);
return attributes.Length > 0 ? (TAttribute)attributes[0] : null;
}
public static bool HasAttribute<TAttribute>(this ICustomAttributeProvider parameterInfo) where TAttribute : Attribute
{
object[] attributes = parameterInfo.GetCustomAttributes(typeof(TAttribute), false);
return attributes.Length > 0 ? true : false;
}
public static string ToFriendlyEnum(this Enum type)
{
return type.GetType().HasAttribute<DescriptionAttribute>() ? type.GetType().GetAttribute<DescriptionAttribute>().Description : type.ToString().ToFriendlyEnum();
}
public static string ToFriendlyEnum(this string value)
{
char[] chars = value.ToCharArray();
string output = string.Empty;
for (int i = 0; i < chars.Length; i++)
{
if (i <= 0 || chars[i - 1].ToString() != chars[i - 1].ToString().ToUpper() && chars[i].ToString() != chars[i].ToString().ToLower())
{
output += " ";
}
output += chars[i];
}
return output.Trim();
}
The GetAttribute extension methods could be slightly overkill, but I use them elsewhere in my projects, so they got reused when I wrote my Enum extension. You could easily combine them back into the ToFriendlyEnum(this Enum type) method
GetAttribute 扩展方法可能有点矫枉过正,但我在项目的其他地方使用它们,因此在我编写 Enum 扩展时它们被重用。您可以轻松地将它们组合回 ToFriendlyEnum(this Enum type) 方法

