多國語系 - 在ViewModel Data Annotation Attribute中套用資源檔
前言
以ASP .NET MVC開發網站時,通常會建立ViewModel來對應View中所需資訊,且透過Data Annotation Attribute規範該屬性是否必填、最大長度上限、及資料型態等,最後頁面上若使用@EditorFor()及@Html.ValidationMessageFor()方法來產出Html時,就會依照屬性Attribute來產出驗證代碼及錯誤訊息。
如下所示,畫面會依Data Annotation Attribute來檢核資料,並且當錯誤發生時顯示指定的錯誤訊息;但當面對多國語系網站時,就必須將錯誤訊息文字抽出至資源檔,然後依照各語系的資源檔來呈現各個錯誤訊息。如何實做呢? 以下將進行說明。
實作說明
原始ViewModel如下,紅線的文字部分將在多國語系的實作中改變取自於資源檔
ViewModel中比較常使用到Data Annotation Attribute為 Required、MaxLength、MinLength、EmailAddress等,因此可以建立共用的資源檔(validation.resx)來依語系顯示錯誤訊息;另外,ViewModel上的Display Attribute則可獨自建立該ViewModel資源檔(HomeContact.resx)。示意結構約略如下。
因此建立共用的Validation資源檔如下
HomeContactViewModel專屬資源檔如下
接著以下列方式套用資源檔來呈現各語系文字,填入指定SourceName及SourceType於Attribute中即可。
注意在EmailAddress中須設定ErrorMessage = null才不會發生錯誤,這是.Net 4.5的已知問題,詳情參考EmailAddress attribute is unable to load error message from resource文章。以下為完整測試代碼。
public class HomeContactViewModel
{
[Display(Name = "VisitorName", ResourceType = typeof(Geker.Resource.ViewModels.Home.HomeContact))]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Geker.Resource.ViewModels.Validation))]
[MaxLength(50, ErrorMessageResourceName = "MaxLength", ErrorMessageResourceType = typeof(Geker.Resource.ViewModels.Validation))]
public string VisitorName { get; set; }
[Display(Name = "Email", ResourceType = typeof(Geker.Resource.ViewModels.Home.HomeContact))]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Geker.Resource.ViewModels.Validation))]
[MaxLength(250, ErrorMessageResourceName = "MaxLength", ErrorMessageResourceType = typeof(Geker.Resource.ViewModels.Validation))]
[EmailAddress(ErrorMessage = null, ErrorMessageResourceName = "EmailAddress", ErrorMessageResourceType = typeof(Geker.Resource.ViewModels.Validation))]
public string Email { get; set; }
[Display(Name = "Subject", ResourceType = typeof(Geker.Resource.ViewModels.Home.HomeContact))]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Geker.Resource.ViewModels.Validation))]
public string Subject { get; set; }
[Display(Name = "Message", ResourceType = typeof(Geker.Resource.ViewModels.Home.HomeContact))]
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Geker.Resource.ViewModels.Validation))]
public string Message { get; set; }
}
最後來驗證一下效果
使用英文語系時,正確顯示英文錯誤提示訊息及標題
使用日文語系時,正確顯示日文錯誤提示訊息及標題
希望此篇文章可以幫助到需要的人
若內容有誤或有其他建議請不吝留言給筆者喔 !