C'est une vieille question, mais je pense que c'est un problème très courant, et voici ma solution en MVC 3.
Tout d'abord, un modèle T4 est nécessaire pour générer des constantes afin d'éviter les chaînes désagréables. Nous avons un fichier de ressources 'Labels.resx' qui contient toutes les chaînes d'étiquettes. Par conséquent, le modèle T4 utilise directement le fichier de ressources,
<#@ template debug="True" hostspecific="True" language="C#" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="C:\Project\trunk\Resources\bin\Development\Resources.dll" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Resources" #>
<#
var resourceStrings = new List();
var manager = Resources.Labels.ResourceManager;
IDictionaryEnumerator enumerator = manager.GetResourceSet(CultureInfo.CurrentCulture, true, true)
.GetEnumerator();
while (enumerator.MoveNext())
{
resourceStrings.Add(enumerator.Key.ToString());
}
#>
// Ce fichier est généré automatiquement. NE MODIFIEZ PAS le contenu à l'intérieur.
namespace Lib.Const{
public static class LabelNames{
<#
foreach (String label in resourceStrings){
#>
public const string <#=label#> = "<#=label#>";
<#
}
#>
}
}
Ensuite, une méthode d'extension est créée pour localiser le 'DisplayName',
using System.ComponentModel.DataAnnotations;
using Resources;
namespace Web.Extensions.ValidationAttributes
{
public static class ValidationAttributeHelper
{
public static ValidationContext LocalizeDisplayName(this ValidationContext context)
{
context.DisplayName = Labels.ResourceManager.GetString(context.DisplayName) ?? context.DisplayName;
return context;
}
}
}
L'attribut 'DisplayName' est remplacé par l'attribut 'DisplayLabel' afin de lire automatiquement dans 'Labels.resx',
namespace Web.Extensions.ValidationAttributes
{
public class DisplayLabelAttribute :System.ComponentModel.DisplayNameAttribute
{
private readonly string _propertyLabel;
public DisplayLabelAttribute(string propertyLabel)
{
_propertyLabel = propertyLabel;
}
public override string DisplayName
{
get
{
return _propertyLabel;
}
}
}
}
Après tout ce travail de préparation, il est temps de modifier ces attributs de validation par défaut. J'utilise l'attribut 'Required' comme exemple,
using System.ComponentModel.DataAnnotations;
using Resources;
namespace Web.Extensions.ValidationAttributes
{
public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute
{
public RequiredAttribute()
{
ErrorMessageResourceType = typeof (Errors);
ErrorMessageResourceName = "Required";
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return base.IsValid(value, validationContext.LocalizeDisplayName());
}
}
}
Maintenant, nous pouvons appliquer ces attributs dans notre modèle,
using Web.Extensions.ValidationAttributes;
namespace Web.Areas.Foo.Models
{
public class Person
{
[DisplayLabel(Lib.Const.LabelNames.HowOldAreYou)]
public int Age { get; set; }
[Required]
public string Name { get; set; }
}
}
Par défaut, le nom de la propriété est utilisé comme clé pour rechercher dans 'Label.resx', mais si vous le définissez via 'DisplayLabel', il l'utilisera à la place.
2 votes
Que diriez-vous de Display(ResourceType=typeof(ResourceStrings),Name="MyPropertyy") voir msdn.microsoft.com/en-us/library/…
0 votes
@Peter lit attentivement le post, il veut exactement le contraire, en utilisant des ResourceStrings et des vérifications à la compilation, et non des chaînes codées en dur...