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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.