[多國語系] 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/