Search code examples
c#localization

C# DisplayAttribute.GetName with specific culture


Suppose we have an enum:

public enum Foo 
{ 
   [Display(ResourceType = typeof(ModelStrings), Name = "Foo_Bar_Name")]
   Bar,
   [Display(ResourceType = typeof(ModelStrings), Name = "Foo_Far_Name")]
   Far 
}

And we have the resource ModelStrings with multiple locales.

ModelStrings.en-US.resx, ModelStrings.pt-BR.resx, ModelStrings.fr-FR.resx, etc..

How can I do something like this, to retrieve the resource value of a specific culture?

Foo myEnum = Foo.Bar;

var displayName = myEnum.GetDisplayName("pt-BR");

Solution

  • A little bit of reflection nicely provided as an extension method over Enum type can do the trick, since every resource, per default, has an public static instance of the ResourceManager class, responsible for managing resources.

    using System;
    using System.ComponentModel.DataAnnotations;
    using System.Globalization;
    using System.Reflection;
    using System.Resources;
    // ...
    
    public static class EnumExtensions
    { 
         public static string GetDisplayName(this Enum enumValue, string cultureName)
         {
             return GetDisplayName(enumValue, CultureInfo.GetCultureInfo(cultureName ?? CultureInfo.CurrentCulture.Name));
         }
    
         public static string GetDisplayName(this Enum enumValue, CultureInfo cultureInfo)
         {
             var attribute = enumValue.GetType().GetMember(enumValue.ToString())[0].GetCustomAttribute<DisplayAttribute>();
    
             var resourceType = attribute.ResourceType;
             var resourceKey = attribute.Name;
    
             var resourceManagerMethodInfo = resourceType.GetProperty(nameof(ResourceManager), BindingFlags.Public | BindingFlags.Static);
    
             var resourceManager = (ResourceManager)resourceManagerMethodInfo?.GetValue(null);
    
             return resourceManager?.GetString(resourceKey, cultureInfo);
         }
     }
    

    So, we can simply use it like this:

    Foo myEnum = Foo.Bar;
    
    var displayName = myEnum.GetDisplayName("pt-BR"); // The extension method.
    

    Tested on .NET Core 3.1