枚举[显示(名称)本地化MVC 4

时间:2013-02-05 15:59:04

标签: enums data-annotations

我有一个包含国家的枚举:

public enum CountryEnum
{
    [Display(Name = "AF", ResourceType = typeof(Global))]
    AF,

    [Display(Name = "AL", ResourceType = typeof(Global))]
    AL,

    [Display(Name = "DZ", ResourceType = typeof(Global))]
    DZ,
};

如您所见,我使用DataAnnotations来定位值。

现在我想显示一个包含所有本地化国家/地区名称的下拉列表。我想出了这段代码:

public static string GetDisplayName<TEnum>(TEnum value)
{        
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DisplayAttribute[] attributes = 
        (DisplayAttribute[])fi.GetCustomAttributes(
            typeof(DisplayAttribute), false);

        if ((attributes != null) && (attributes.Length > 0))
            return attributes[0].Name;
        else
            return value.ToString();
}

我有一个使用上述方法的Html助手:

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

    IEnumerable<SelectListItem> items = from value in values
                                        select new SelectListItem
                                        {
                                            Text = GetDisplayName(value),
                                            Value = value.ToString(),
                                            Selected = value.Equals(metadata.Model)
                                        };

    // If the enum is nullable, add an 'empty' item to the collection
    if (metadata.IsNullableValueType)
        items = SingleEmptyItem.Concat(items);

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

DropDown正确呈现,但GetDisplayName不返回本地化值,只显示名称属性(例如第一个条目的AF)。

如何修改GetDisplayName方法以返回本地化值?

2 个答案:

答案 0 :(得分:2)

您需要更新GetDisplayName方法以使用GetName()方法,而不是Name的{​​{1}}属性。

像这样:

DisplayAttribute

来自public static string GetDisplayName<TEnum>(TEnum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); DisplayAttribute[] attributes = (DisplayAttribute[])fi. GetCustomAttributes(typeof(DisplayAttribute), false); if ((attributes != null) && (attributes.Length > 0)) return attributes[0].GetName(); else return value.ToString(); } 的MSDN文档:

  

不要使用此属性来获取Name属性的值。使用   改为使用GetName方法。

DisplayAttribute.Name方法的MSDN文档可以这样说:

  

返回Name属性的本地化字符串,如果是   已指定ResourceType属性和Name属性   代表资源键;否则,非本地化的值   姓名财产。

答案 1 :(得分:0)

我遇到了类似的问题,像你一样设置了显示属性(因为类使用相同的属性来加载本地化,因此更容易),所以拿起你的初始代码并稍微调整一下,现在它将本地化​​字符串显示为预期。我不认为这是最聪明或最优化的方式,但它确实有效。希望这就是你的意图。

public static string GetDisplayName<TEnum>(TEnum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());

        DisplayAttribute[] attributes = (DisplayAttribute[])fi.
            GetCustomAttributes(typeof(DisplayAttribute), false);

        if ((attributes != null) && (attributes.Length > 0))
        {
            string key = attributes[0].Name;
            string localizedString = attributes[0].ResourceType.GetProperty(key).GetValue("").ToString();
            return localizedString;
        }
        else
            return value.ToString();
    }