I can use ErrorMessageResourceName and ErrorMessageResourceType to translate rules into my language. But how do I translate class name and properties?
Currently I get something like Valideringsmeddelande för 'LastName' as validation message. I want LastName to be localized too.
As far as I know that
ErrorMessage,ErrorMessageResourceName, andErrorMessageResourceTypeproperties are not used by Validation Application Block. They are included in Validation Application Block 5.0, because VAB'sBaseValidationAttributenow inherits fromSystem.ComponentModel.DataAnnotations.ValidationAttribute. These properties are defined in DataAnnotations'ValidationAttribute. By inheriting from DataAnnotations, the applications and frameworks can validate a model without having a dependency on VAB (such as the validation that ASP.NET MVC does for instance).What you can do is use VAB's
MessageTemplateResourceNameandMessageTemplateResourceTypeand don't use any markers and use a text specific to the property. For instance, put this complete text in your resource: "Valideringsmeddelande för efternamn" (sorry if the translation is crappy; I used Google translate).Update:
I did some digging around in the library and unfortunately there is no easy way around this. Below is the code for the
GetMessagemethod that is defined in theValidatorbase class that is located inMicrosoft.Practices.EnterpriseLibrary.Validation.As you can see, the error message is generated using the
MessageTemplateas format string together with theobjectToValidate,key, andTagas formatting arguments. TheTagis a value that you can define in aValidationAttributeand is therefore static and can not be culture specific. When you are validating a property, the suppliedkeywill always be the name of that property. This name will be supplied by the framework by reflecting over the validated type.You can make the name more user friendly and language specific, by defining a new
Validatorand overriding theGetMessage. This way you can fetch a culture dependent text based on the property name from a resource. The problem is however, that you will have to create a sub class for every validation attribute you wish to use and for each validation attribute you must inherit the supporting validator class. While this shouldn’t be that much code per attribute and per validator, it would still be very painful to maintain such a code base.I think it would be easier to simply define the complete message including user friendly, language specific name in the resource.
Update 2:
I thought of something that might possibly help. When your application only has to be able to display a single language at a time, there may be a work around. This won't work for web applications were the displayed messages are localized based on the thread's current culture, but it might work for desktop applications were you can configure language specific texts in the application's configuration file.
When you define the validation rules in the application's configuration file (which is a model VAB supports), you can use the Tag attribute with a language specific string.
Take a close look at the tag
tag="efternamn". When you put the {2} placeholder in the format string in your resource, it will get replaced by the string defined in tag. In other words, this resource string:will result in this validation message:
Of course for this to work, your configuration must be localized. This wouldn’t be a good solution for web applications.
But... you can also go one step further and build an
IConfigurationSourceimplementation that returns aValidationSettingsinstance that is based on the thread's current culture. In this scenario you will have to build the configuration in code. Here is an example of how to do this:You can supply an instance of that
MyConfigurationSourceto theValidationFactoryor, if you want better integration, hook up this type it in the VAB configuration.Note however that building validation rules in code is currently a lot of work, especially because VAB does not (yet) have a decent fluent configuration API (I complained about this here). I'm in the process of writing an API that makes it much easier to do so (keep an eye on my blog for that).
Good luck.