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の国際化検証
終わります.