Enum DisplayName:模板只能在有字段访问权限的情况下使用

本文关键字:权限 访问权 访问 情况下 字段 DisplayName Enum | 更新日期: 2023-09-27 18:15:37

我知道已经有关于这个的其他线程了。我一直在读。这是我得到的:

namespace Books.Entities
{
    public enum Genre
    {
        [Display(Name = "Non Fiction")]
        NonFiction,
        Romance,
        Action,
        [Display(Name = "Science Fiction")]
        ScienceFiction
    }
}

模型:

namespace Books.Entities
{
    public class Book
    {
        public int ID { get; set; }
        [Required]
        [StringLength(255)]
        public string Title  { get; set; }
        public Genre Category { get; set; }
    }
}

然后,在视图中:

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Title)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Category)
    </td>
</tr>

我认为框架会自动使用DisplayName属性。看起来很奇怪,它没有。但是,不管。试图克服与扩展(发现这在同一问题的另一个线程)…

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();
    }
}

看起来应该可以工作,但是当我尝试使用它时:

 @Html.DisplayFor(modelItem => item.Category.GetDispayName())

我得到这个错误:

{"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions."}  

Enum DisplayName:模板只能在有字段访问权限的情况下使用

你可能想要考虑的一件事是为Enum添加一个DisplayTemplate,你的@Html.DiplayFor()将使用它。

如果在~/Views/Shared文件夹中创建一个名为DisplayTemplates的文件夹,则添加一个名为Enum的新视图。并将以下代码添加到视图

@model Enum
@{
    var display = Model.GetDisplayName();
}
@display

那么你所要做的就是在其他视图中使用@Html.DisplayFor(modelItem => item.Category)

如果没有description属性,你的GetDisplayName代码会抛出一个错误,所以你可能想使用像 这样的东西
public static string GetDisplayName(this Enum enumValue)
    {
        Type type = enumValue.GetType();
        string name = Enum.GetName(type, enumValue);
        if (name != null)
        {
            FieldInfo field = type.GetField(name);
            if (field != null)
            {
                DescriptionAttribute attr =
                       Attribute.GetCustomAttribute(field,
                         typeof(DescriptionAttribute)) as DescriptionAttribute;
                if (attr != null)
                {
                    return attr.Description;
                }
            }
        }
        return name;
    }

好的,找到了几个方法来解决这个问题。首先,正如mxmissile建议的那样,只需使用:

@item.Category.GetDisplayName()

结果错误信息告诉了我我需要知道的。我只是没有抓住@Html.DisplayFor()是一个模板,我不能使用它与helper扩展。

但是,我在这里找到了一个更好的解决方案:

http://www.codeproject.com/Articles/776908/Dealing-with-Enum-in-MVC

在这个解决方案中,作者提供了一个默认情况下适用于所有枚举的显示模板,而不必使用GetDisplayName()。使用此解决方案,原始代码可以正常工作:

@Html.DisplayFor(modelItem => item.Category)

此外,默认情况下,它将全面工作。

(注意:这都是假设您正在使用MVC5.x)