5

[Display]列挙型の 1 つに属性を使用しました。

    public enum eCommentType
    {
        [Display(ResourceType = typeof(FaultManagementStrings), Name = "NormalComment")]
        NormalComment = 0,

        [Display(ResourceType = typeof(FaultManagementStrings), Name = "OpenningComment")]
        OpenningComment = 1,

        [Display(ResourceType = typeof(FaultManagementStrings), Name = "StartProgressComment")]
        StartProgressComment = 2,

        [Display(ResourceType = typeof(FaultManagementStrings), Name = "ClouserComment")]
        ClouserComment = 3,

        [Display(ResourceType = typeof(FaultManagementStrings), Name = "ReopennignComment")]
        ReopennignComment = 4
    }

指定されたリソースから Display 属性値を取得する既存の MVC 機能を再利用する拡張メソッドを作成することは可能ですか?

私はそのような何か...

@Html.GetEnumDisplayAttributeValue(c=> comment.CommentType)

私は、必要なリフレクションを実装し、リソースタイプの値と呼び出しリソースマネージャーなどを見つける何かを作成できることを知っています...しかし、mvcの既存の組み込み機能を使用することはおそらく可能だと思います..結局のところ、LabelForヘルパーを呼び出すと、それはすでに行われています。

可能ですか、それとも車輪を再発明する必要がありますか?

4

2 に答える 2

5

私は同じ問題を抱えていて、これらの拡張メソッドを作成しました:

using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;

public static class EnumHelper
{
    private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = string.Empty, Value = string.Empty } };

    public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
    {
        return htmlHelper.EnumDropDownListFor(expression, null);
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var enumType = GetNonNullableModelType(metadata);
        var values = Enum.GetValues(enumType).Cast<TEnum>();

        var items =
            values.Select(value => new SelectListItem
                                       {
                                           Text = GetName(value),
                                           Value = value.ToString(),
                                           Selected = value.Equals(metadata.Model)
                                       });

        if (metadata.IsNullableValueType)
        {
            items = SingleEmptyItem.Concat(items);
        }

        return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
    }

    private static string GetName<TEnum>(TEnum value)
    {
        var displayAttribute = GetDisplayAttribute(value);

        return displayAttribute == null ? value.ToString() : displayAttribute.GetName();
    }

    private static DisplayAttribute GetDisplayAttribute<TEnum>(TEnum value)
    {
        return value.GetType()
                    .GetField(value.ToString())
                    .GetCustomAttributes(typeof(DisplayAttribute), false)
                    .Cast<DisplayAttribute>()
                    .FirstOrDefault();
    }

    private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
    {
        var realModelType = modelMetadata.ModelType;
        var underlyingType = Nullable.GetUnderlyingType(realModelType);

        return underlyingType ?? realModelType;
    }
}

ビューでこれらの拡張メソッドを次のように使用できます。

@Html.EnumDropDownListFor(c=> comment.CommentType)

に応じて、列挙値の名前を含むドロップダウンリストが表示されるはずですDisplayAttribute

表示された列挙値の実際の取得は、GetNameメソッドで行われます。このメソッドは、最初にGetDisplayAttributeメソッドを使用して列挙値の取得を試みDisplayAttributeます。列挙値が実際に で装飾されている場合はDisplayAttribute、それを使用して表示する名前を取得します。がない場合DisplayAttributeは、列挙値の名前を返すだけです。

于 2013-05-15T12:12:31.050 に答える