3

我知道已经有其他关于此的线程。我一直在读它们。这是我所拥有的:

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."}  
4

2 回答 2

4

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

如果您在文件夹中创建一个~/Views/Shared名为的文件夹DisplayTemplates,请添加一个名为 Enum.cshtml 的新视图并将此代码添加到该视图中

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

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

顺便说一句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;
    }
于 2015-10-02T15:40:14.957 回答
2

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

@item.Category.GetDisplayName()

结果错误消息告诉我我需要知道的确切内容。我只是没有注意到 @Html.DisplayFor() 是一个模板,我不能将它与辅助扩展一起使用。

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

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

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

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

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

注意:这一切都假设您使用的是 MVC5.x)

于 2015-10-02T15:39:33.447 回答