Localized Attribute parameters in C#
In C#, attribute parameters require to be a constant expression, typeof or array creation expression.
Various libraries, like for example Castle validator, allow specifying passing what seems like localized error messages to attribute constructor:
//this works
[ValidateNonEmpty("Can not be empty")]
//this does not compile
[ValidateNonEmpty(Resources.NonEmptyValidationMessage)]
Is there any way how to approach this problem and localize these arguments?
In case there is no wo开发者_JAVA技巧rkaround for this when using Castle Validator, is there a validation library similar to Castle Validator that allows localization of validation messages?
EDIT: I found how Data Annotations validation library approaches this problem. Very elegant solution: http://haacked.com/archive/2009/12/07/localizing-aspnetmvc-validation.aspx
We had a similar issue, although not with Castle. The solution we used was simply to define a new attribute which was derived from the other one, and which used the constant string as a lookup to the resources manager, and fell back to the key string itself if none was found.
[AttributeUsage(AttributeTargets.Class
| AttributeTargets.Method
| AttributeTargets.Property
| AttributeTargets.Event)]
public class LocalizedIdentifierAttribute : ... {
public LocalizedIdentifierAttribute(Type provider, string key)
: base(...) {
foreach (PropertyInfo p in provider.GetProperties(
BindingFlags.Static | BindingFlags.NonPublic)) {
if (p.PropertyType == typeof(System.Resources.ResourceManager)) {
ResourceManager m = (ResourceManager) p.GetValue(null, null);
// We found the key; use the value.
return m.GetString(key);
}
}
// We didn't find the key; use the key as the value.
return key;
}
}
Usage is something like:
[LocalizedIdentifierAttribute(typeof(Resource), "Entities.FruitBasket")]
class FruitBasket {
// ...
}
Then each locale-specific resource file can define its own Entities.FruitBasket
entry, as needed.
It works out of the box:
[ValidateNonEmpty(
FriendlyNameKey = "CorrectlyLocalized.Description",
ErrorMessageKey = "CorrectlyLocalized.DescriptionValidateNonEmpty",
ResourceType = typeof (Messages)
)]
public string Description { get; set; }
精彩评论