18

What's the recommended way to display localized enum properties in MVC2?

If I have a model like this:

public class MyModel {
  public MyEnum MyEnumValue { get; set; } 
}

and a line in the view like this:

<%: Html.DisplayFor(model => model.MyEnumValue) %>

I was hoping to just annotate the enum values with DisplayAttribute like this:

public enum MyEnum
{
    [Display(Name="EnumValue1_Name", ResourceType=typeof(Resources.MyEnumResources))]
    EnumValue1,
    [Display(Name="EnumValue2_Name", ResourceType=typeof(Resources.MyEnumResources))]
    EnumValue2,
    [Display(Name="EnumValue3_Name", ResourceType=typeof(Resources.MyEnumResources))]
    EnumValue3
}

That's not supported. It seems there's something else needed. What's the nicest way to implement it?

3
  • What do you want to display as the end result? Commented Aug 19, 2010 at 12:23
  • The appropriate translation from the resource file, i.e. EnumValue1_Name etc. Commented Aug 19, 2010 at 12:46
  • take a look at this question may be it is usefull! stackoverflow.com/questions/3431515/… Commented Aug 31, 2010 at 13:45

2 Answers 2

7

You can try using the DescriptionAttribute for this.

E.g.

In the view model:

public enum MyEnum
        {
             [Description("User Is Sleeping")]
            Asleep,
             [Description("User Is Awake")]
            Awake
        }

 public string GetDescription(Type type, string value)
        {
            return ((DescriptionAttribute)(type.GetMember(value)[0].GetCustomAttributes(typeof(DescriptionAttribute), false)[0])).Description;
        }

In the view:

Model.GetDescription(Model.myEnum.GetType(), Model.myEnum) to retrieve the value set in Description. 

I am using something similar to set the displayname and value in my Html.Dropdown.

Sign up to request clarification or add additional context in comments.

2 Comments

Sure, but that's not localized. And Views need to know whether they're displaying an Enum or something else, and I'd hoped to separate that concern. I was hoping to extend the ModelMetadataProvider or something like that. I'll post the answer if I find it.
Yes, you are right. This won't work for localization req. I'll keep the post though. Some one might find it useful for other scenarios.
3

I also use the Display annotation. Here's what I ended up using, which works for BOTH a property and enum members.

Here's my enum:

public enum TagOrderStatus
{
    [Display(ResourceType = typeof(TagStrings), Name = "TagOrderStatus_NotOrdered")]
    NotOrdered = 0,
    [Display(ResourceType = typeof(TagStrings), Name = "TagOrderStatus_ToOrder")]   
    ToOrder = 1,
    [Display(ResourceType = typeof(TagStrings), Name = "TagOrderStatus_Ordered")]   
    Ordered = 2
}

Then my little do-it-all utility method:

public static string GetLocalizedDisplay<TModel>(string pPropertyName)
{
    DisplayAttribute attribute;

    if (typeof(TModel).IsEnum)
    {
        MemberInfo member = typeof(TModel).GetMembers().SingleOrDefault(m => m.MemberType == MemberTypes.Field && m.Name == pPropertyName);
        attribute = (DisplayAttribute)member.GetCustomAttributes(typeof(DisplayAttribute), false)[0];
    }
    else
    {
        PropertyInfo property = typeof(TModel).GetProperty(pPropertyName);
        attribute = (DisplayAttribute)property.GetCustomAttributes(typeof(DisplayAttribute), true)[0];
    }

    if (attribute.ResourceType != null)
        return new ResourceManager(attribute.ResourceType).GetString(attribute.Name);
    else
        return attribute.Name;
}

This can then be used this way to obtain a single member display property for an enum member:

string disp = GetLocalizedDisplay<Tag.TagOrderStatus>("Ordered");

Or a property:

string disp = GetLocalizedDisplay<Tag>("OwnerName");

I love Generics. Hope this helps!!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.