MVC.net отображает отображаемое имя enum без необходимости ссылаться на тип перечисления в представлении
У меня есть следующий вспомогательный метод в классе 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;
}
Затем я вызываю это из представления следующим образом:
<p>
@{var rel = Model.GetEnumDisplayName<Enums.wheteverEnum>(Model.wheteverEnum); }
@rel
</p>
Вопрос: могу ли я работать с этим методом, поэтому мне не нужно указывать тип enum
? В принципе, я хотел бы сделать это для всех enum
s:
@Model.GetEnumDisplayName(Model.wheteverEnum)
Нет typeof
, no T
, не нужно добавлять ссылку в пространство имен Enums
в представлении...
Возможные?
Ответы
Ответ 1
Вы можете просто удалить параметр типа и сделать его методом расширения.
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()
Ответ 2
Не могли бы вы написать это как метод расширения? Что-то вроде...
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;
}
}
Использование:
@Model.WhateverEnum.ToDescription();
Ответ 3
Хорошая работа @jrummell!
Я добавил небольшую настройку ниже, в которой фиксируется сценарий, в котором перечисление не имеет связанного атрибута Дисплей (в настоящее время он генерирует исключение)
/// <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;
}
Ответ 4
Ответ @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
Ответ 5
для всех, кто мог бы обратиться к этому вопросу, я нашел это намного проще, чем что-либо другое:
https://www.codeproject.com/articles/776908/dealing-with-enum-in-mvc
Просто создайте папку "DisplayTemplate" в разделе "Views\Shared" и создайте пустое представление (Name it "Enum" ) в новой папке "DisplayTemplate" и скопируйте этот код в него
@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)
}
Ответ 6
Вот метод расширения, который я написал, чтобы сделать именно это... у него есть немного дополнительной логики, чтобы анализировать имена Enum и разделять прописными буквами. Вы можете переопределить любое имя, используя атрибут отображения
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();
}
Методы расширения GetAttribute могут быть немного переполнены, но я использую их в других проектах, поэтому они снова использовались, когда я писал расширение Enum. Вы можете легко объединить их обратно в метод ToFriendlyEnum (этот тип перечисления)
Ответ 7
Предлагаемые решения для меня не работают с 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;
}