ASP.NET MVCの国際化問題
9848 ワード
ブログ園ではこの投稿話が全面的に行われていますが、まだ優雅ではないと思います.全体が混乱しているように見えます.海外のこのお兄さんの投稿のように、きれいに処理されています.簡単な記録は以下の通りです.
通常の国際化処理方法
public class User
{
[Required(ErrorMessageResourceName = "Validation_Required", ErrorMessageResourceType = typeof(ModelTranslations))]
[LocalizedDisplayNameAttribute("User_Id", NameResourceType=typeof(ModelTranslations))]
public int Id { get; set; }
[Required(ErrorMessageResourceName = "Validation_Required", ErrorMessageResourceType = typeof(ModelTranslations))]
[StringLength(40, ErrorMessageResourceName = "Validation_StringLength", ErrorMessageResourceType = typeof(ModelTranslations))]
[LocalizedDisplayNameAttribute("User_FirstName", NameResourceType=typeof(ModelTranslations))]
public string FirstName { get; set; }
[Required(ErrorMessageResourceName = "Validation_Required", ErrorMessageResourceType = typeof(ModelTranslations))]
[StringLength(40, ErrorMessageResourceName = "Validation_StringLength", ErrorMessageResourceType = typeof(ModelTranslations))]
[LocalizedDisplayNameAttribute("User_LastName", NameResourceType=typeof(ModelTranslations))]
public string LastName { get; set; }
}
混乱しているように見えます.
public class User
{
[Required]
[LocalizedDisplayNameAttribute("User_Id")]
public int Id { get; set; }
[Required]
[StringLength(40)]
[LocalizedDisplayNameAttribute("User_FirstName")]
public string FirstName { get; set; }
[Required]
[StringLength(40)]
[LocalizedDisplayNameAttribute("User_LastName")]
public string LastName { get; set; }
}
きれいになったのではないでしょうか.しかし、このきれいな代価は背後にコードを書くことです.
public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute
{
private string _displayName;
public RequiredAttribute()
{
ErrorMessageResourceName = "Validation_Required";
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
_displayName = validationContext.DisplayName;
return base.IsValid(value, validationContext);
}
public override string FormatErrorMessage(string name)
{
var msg = LanguageService.Instance.Translate(ErrorMessageResourceName);
return string.Format(msg, _displayName);
}
}
これは属性を検証する実装コードです.
ublic class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
private PropertyInfo _nameProperty;
private Type _resourceType;
public LocalizedDisplayNameAttribute(string className, string propertyName)
: base(className + (propertyName == null ? "_Class" : ("_" + propertyName)))
{
}
public override string DisplayName
{
get
{
return LanguageService.Instance.Translate(base.DisplayName) ?? "**" + base.DisplayName + "**";
}
}
}
DisplayName属性を実装する実装コードです
public class LanguageService
{
private static LanguageService _instance = new LanguageService();
private List<ResourceManager> _resourceManagers = new List<ResourceManager>();
private LanguageService()
{
}
public static LanguageService Instance { get { return _instance; } }
public void Add(ResourceManager mgr)
{
_resourceManagers.Add(mgr);
}
public string Translate(string key)
{
foreach (var item in _resourceManagers)
{
var value = item.GetString(key);
if (value != null)
return value;
}
return null;
}
}
これは、上記のクラスに依存する管理リソースのコードです.
しかし、上記の解決策はクライアント検証に問題があり、以下は簡単な実現である.
public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute>
{
public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
: base(metadata, context, attribute)
{
}
public static void SelfRegister()
{
DataAnnotationsModelValidatorProvider
.RegisterAdapter(
typeof (RequiredAttribute),
typeof (RequiredAttributeAdapter));
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
return new[] { new ModelClientValidationRequiredRule(ErrorMessage) };
}
}
そしてGlobalでasaxに一言
RequiredAttributeAdapter.SelfRegister();
Technoratiラベル:
ASP.NET MVCの国際化検証
終わります.