4
从资源属性值

我已经使用了[Display]属性为我的枚举之一:获得[显示]在MVC

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 
    } 

是否有可能建立一种推广方法,将重用得到的exsisting MVC finctionallity显示指定资源的属性值?

我就什么类似的东西...

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

我知道我可以WIRTE的东西,将实施必要的反思和寻找资源类型的值和呼叫资源管理等..但我认为也许可以使用现有的mvc内置功能..毕竟,当您拨打LabelFor助手时,它已经完成了。

是可能或应该重新发明轮子?

回答

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,我们只返回枚举值的名称。

+0

你能更具体吗?确切负责从显示属性和资源中提取信息的方法是什么? – Mortalus

+1

@Mortalus我刚更新了描述。你应该关注的是'GetName'和'GetDisplayAttribute'方法,它们被用来提取display属性。 –

1

正如预料的那样,微软在MVC 5.1(RC1)中包含了一个EnumDropDownListFor HTML助手方法。