[多國語系] MVC ViewModel自動載入語系資源-驗證訊息
中文 | 英文 |
而要加上自訂的語系的話則需要再指定ErrorMessageResourceName及ErrorMessageResourceType
改善目標
- 不要設定語系名稱及語系型別
- 自動為驗證Property跟資源檔作結合
1.先為資源名稱規則化
如下圖所示:以Model+底線+Property+驗證特性來命名2.實作相關的驗證Adapter
如下目前只列出實作RequiredAttributeAdapter,其他請參考原始碼,程式重點:先判斷是否已有自行設定ErrorMessage,沒有則取資源檔,而取回若為空值則回傳系統內建訊息public class LocalizedRequiredAttributeAdapter : RequiredAttributeAdapter { public LocalizedRequiredAttributeAdapter( ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute) : base(metadata, context, attribute) { } public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() { string errorMessage = null; if (this.Attribute.ErrorMessage == null && (this.Attribute.ErrorMessageResourceName == null || this.Attribute.ErrorMessageResourceType == null)) errorMessage = MvcApplication.GlobalResourceStringProvider.GetModelString(Metadata.ContainerType, Metadata.PropertyName, "Required"); if (string.IsNullOrEmpty(errorMessage)) errorMessage = ErrorMessage; //取不到則還原成預設值 return new[] { new ModelClientValidationRequiredRule(errorMessage) }; } }
3.在Global.asax註冊相關的Adapter
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); ResourceStringProvider rp = new ResourceStringProvider(Local.ResourceManager); ModelMetadataProviders.Current = new LocalizedModelMetadataProvider(rp); GlobalResourceStringProvider = rp; //註冊Adapter DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredAttribute), typeof(LocalizedRequiredAttributeAdapter)); DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(StringLengthAttribute), typeof(LocalizedStringLengthAttributeAdapter)); DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RangeAttribute), typeof(LocalizedRangeAttributeAdapter)); DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(System.ComponentModel.DataAnnotations.CompareAttribute), typeof(LocalizedCompareAttributeAdapter)); }
4.大功告成-顯示結果
針對要驗證的屬性不用再指定語系名稱及型別
public class ProductModel { public int ProductId { get; set; } [StringLength(3)] [Required] public string ProductName { get; set; } public DateTime CreateDate { get; set; } [Range(100D, 300.55D)] public decimal Price { get; set; } public int Qty { get; set; } [Compare("Qty")] public int Qty_Old { get; set; } }
參考來源
http://thatextramile.be/blog/2011/04/customizing-asp-net-mvcs-required-property-validation-messages/
http://social.msdn.microsoft.com/Forums/en-US/77514514-8375-480a-a905-e636eed20064/aspnet-mvc-validate-?forum=236
本篇原始碼
https://github.com/kimx/LocalizedModelProviderLab/