Geeks With Blogs

@BrianSchroer
  • BrianSchroer I see a lot of fans wearing #stlcards red at the Cincinnati ballpark. ;) about 451 days ago
  • BrianSchroer What part of "What part of x do you not understand" do you think is clever? about 451 days ago
  • BrianSchroer Anonymous notes to those with whom I shared a conference call today: 1) The "t" is silent in "across". 2) "Uniquer" is not a word. about 454 days ago
  • BrianSchroer KSDK: "Don't take any chances. Get in the basement now. Now let's hear from our reporter, driving up I-64 TOWARD THE STORM." about 459 days ago
  • BrianSchroer Congratulations to Joanna Schroer & University City High School Class of '13 #UTime about 460 days ago
  • BrianSchroer Ugh. McCarver doing the #stlcards game. This guy makes Hrabosky seem witty and concise by comparison. about 465 days ago

News

Brian Schroer Don't Call Me Mort!

 

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 | Back to top


Comments on this post: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way

# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Requesting Gravatar...
You are a genius. Brilliant solution.
Left by Andrei on Aug 02, 2010 6:27 AM

# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Requesting Gravatar...
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.
Left by foldip on Sep 08, 2010 6:48 AM

# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Requesting Gravatar...
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.
Left by Jorge Perez Luna on Nov 10, 2010 10:23 PM

# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Requesting Gravatar...
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;
Left by Soren on Dec 16, 2010 6:39 AM

# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Requesting Gravatar...
Can this also be used for localization of the error messages.
like in: [Required(ErrorMessage = "RsErrorMustHaveIds")]
Left by Raymond on Jan 13, 2011 8:23 AM

# re: ASP.NET MVC localization DisplayNameAttribute alternatives: a better way
Requesting Gravatar...
Very Nice!!!! THANKS!
Left by You are my personal hero! GREAT! on Jul 13, 2011 8:32 AM

Your comment:
 (will show your gravatar)
 


Copyright © Brian Schroer | Powered by: GeeksWithBlogs.net | Join free