2010-01-23 8 views
1

En C#, les paramètres d'attribut doivent être une expression de création d'expression constante, de typeof ou de tableau.Paramètres d'attribut localisés dans C#

bibliothèques diverses, comme par exemple le château validateur, permettent de spécifier ce qui semble passer des messages d'erreur localisés à l'attribut constructeur:

//this works 
[ValidateNonEmpty("Can not be empty")] 

//this does not compile 
[ValidateNonEmpty(Resources.NonEmptyValidationMessage)] 

Est-il possible comment aborder ce problème et localiser ces arguments?

Dans le cas où il n'existe pas de solution de contournement lors de l'utilisation de Castle Validator, existe-t-il une bibliothèque de validation similaire à Castle Validator qui permet la localisation des messages de validation?

EDIT: J'ai trouvé comment la bibliothèque de validation des annotations de données aborde ce problème. Solution très élégante: http://haacked.com/archive/2009/12/07/localizing-aspnetmvc-validation.aspx

Répondre

0

Il fonctionne hors de la boîte:

[ValidateNonEmpty(
     FriendlyNameKey = "CorrectlyLocalized.Description", 
     ErrorMessageKey = "CorrectlyLocalized.DescriptionValidateNonEmpty", 
     ResourceType = typeof (Messages) 
     )] 
    public string Description { get; set; } 
+0

Merci, ce serait merveilleux, mais la version de ValidateNonEmptyAttribute de Castle Validator que j'utilise n'a pas ces propriétés. Je vois seulement errorMessage, RunWhen, ExecutionOrder et FriendlyName. – Marek

+1

Quelle version du validateur Castle a ces propriétés? Pourriez-vous s'il vous plaît poster un lien de téléchargement? – Marek

+0

Un peu difficile à trouver, mais la version SVN l'a. https://svn.castleproject.org/svn/castle/Components/Validator/trunk/ Merci de le signaler! – Marek

4

Nous avons eu un problème similaire, mais pas avec Castle. La solution que nous avons utilisée était simplement de définir un nouvel attribut dérivé de l'autre, et qui utilisait la chaîne constante comme référence pour le gestionnaire de ressources, et revenait à la chaîne de clé elle-même si aucun n'était trouvé.

[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; 
    } 
} 

L'utilisation est quelque chose comme:

[LocalizedIdentifierAttribute(typeof(Resource), "Entities.FruitBasket")] 
class FruitBasket { 
    // ... 
} 

Ensuite, chaque fichier de ressources spécifiques à l'environnement local peut définir sa propre entrée Entities.FruitBasket, au besoin.

+0

Merci, c'est une solution très élégante façon d'envelopper une bibliothèque existante pour permettre ce comportement. – Marek

+0

Vous pouvez également utiliser'nameof (Entities.FruitBasket) ', l'identifiant de la ressource peut changer. –