MVC.net在视图中获取枚举显示名称,而不必在视图中引用枚举类型

nat*_*hfy 25 generics asp.net-mvc enums c#-4.0 asp.net-mvc-3

我在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;
        }
Run Code Online (Sandbox Code Playgroud)

然后我从这样的视图中调用它:

<p>
@{var rel = Model.GetEnumDisplayName<Enums.wheteverEnum>(Model.wheteverEnum); }
@rel
</p>
Run Code Online (Sandbox Code Playgroud)

问题是 - 我可以使用这种方法,所以我不必告诉它的类型enum吗?基本上我想为所有人做这个enum:

@ Model.GetEnumDisplayName(Model.wheteverEnum)

typeof,不T,不需要Enums在视图中添加对命名空间的引用...

可能?

jru*_*ell 54

您可以简单地删除type参数并使其成为扩展方法.

    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()
Run Code Online (Sandbox Code Playgroud)

  • 为了完整起见,你应该添加一个检查,表明有任何`DisplayAttributes`应用于枚举值,并返回`value.ToString()`作为默认值,如果没有.否则,当你调用`((DisplayAttribute)attrs [0])时,你会得到一个`IndexOutOfRangeException`.名字` (2认同)

dev*_*tal 7

你能不把它写成扩展方法?就像是...

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

@Model.WhateverEnum.ToDescription();
Run Code Online (Sandbox Code Playgroud)


toe*_*.uk 5

干得好!@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;
}
Run Code Online (Sandbox Code Playgroud)