Posts
114
Comments
130
Trackbacks
10
ASP.NET MVC localization DisplayNameAttribute alternatives: a better way

 

In my last post, I talked bout creating a custom class inheriting from System.ComponentModel.DisplayNameAttribute to retrieve display names from resource files:

        [LocalizedDisplayName("RememberMe")]
        public bool RememberMe { get; set; }
 

That’s a lot of work to put an attribute on all of my model properties though. It would be nice if I could intercept the ASP.NET MVC code that analyzes the model metadata to retrieve display names to make it automatically get localized text from my resource files. That way, I could just set up resource file entries where the keys are the property names, and not have to put attributes on all of my properties.

That’s done by creating a custom class inheriting from System.Web.Mvc.DataAnnotationsModelMetadataProvider:

   1:      public class LocalizedDataAnnotationsModelMetadataProvider :
   2:          DataAnnotationsModelMetadataProvider
   3:      {
   4:          protected override ModelMetadata CreateMetadata(
   5:              IEnumerable<Attribute> attributes, 
   6:              Type containerType, 
   7:              Func<object> modelAccessor, 
   8:              Type modelType, 
   9:              string propertyName)
  10:          {
  11:              var meta = base.CreateMetadata
  12:                  (attributes, containerType, modelAccessor, modelType, propertyName);
  13:   
  14:              if (string.IsNullOrEmpty(propertyName)) 
  15:                  return meta;
  16:   
  17:              if (meta.DisplayName == null)
  18:                  GetLocalizedDisplayName(meta, propertyName);
  19:   
  20:              if (string.IsNullOrEmpty(meta.DisplayName))
  21:                  meta.DisplayName = string.Format("[[{0}]]", propertyName);
  22:   
  23:              return meta;
  24:          }
  25:   
  26:          private static void GetLocalizedDisplayName(ModelMetadata meta, string propertyName)
  27:          {
  28:              ResourceManager resourceManager = MyResource.ResourceManager;
  29:              CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
  30:   
  31:              meta.DisplayName = resourceManager.GetString(propertyName, culture);
  32:          }
  33:      }

Line 11 calls the base CreateMetadata method.

Line 17 checks whether the metadata DisplayName property has already been populated by a DisplayNameAttribute (or my LocalizedDisplayNameAttribute). If so, it respects that and doesn’t use my custom localized text lookup.

The GetLocalizedDisplayName method checks for the property name as a resource file key. If found, it uses the localized text from the resource files.

If the key is not found in the resource file, as with my LocalizedDisplayNameAttribute, I return a formatted string containing the property name (e.g. “[[RememberMe]]”) so I can tell by looking at my web pages which resource keys I haven’t defined yet.

It’s hooked up with this code in the Application_Start method of Global.asax:

    ModelMetadataProviders.Current = new LocalizedDataAnnotationsModelMetadataProvider();
posted on Monday, June 14, 2010 6:04 PM Print
Comments
Gravatar
# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Andrei
8/2/2010 6:27 AM
You are a genius. Brilliant solution.
Gravatar
# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
foldip
9/8/2010 6:48 AM
This is a very nice solution. I improved it here and there, but it is the best solution to this problem I've found.
Thank you.
Gravatar
# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Jorge Perez Luna
11/10/2010 10:23 PM
Would this work with MVC ? How do I link the Model to this method? I am new to MVC - c# and for sure have a long way to go. Any additional information of the full solution would be appretiated.

Thanks.
Gravatar
# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Soren
12/16/2010 6:39 AM
Very nice! Normaly i do not code C# or ASP, so this is a great help. I have one question, and i'm pretty sure that it's simple. This Line gives me an error:

ResourceManager resourceManager = MyResource.ResourceManager;
Gravatar
# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Raymond
1/13/2011 8:23 AM
Can this also be used for localization of the error messages.
like in: [Required(ErrorMessage = "RsErrorMustHaveIds")]
Gravatar
# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
You are my personal hero! GREAT!
7/13/2011 8:32 AM
Very Nice!!!! THANKS!

Post Comment

Title *
Name *
Email
Comment *  
 
Tag Cloud