我需要在數據庫中保留我的翻譯,以便用戶可以添加,刪除和更改它們。我將所有翻譯都放在一個帶有複合主鍵(variableName,culture)的表格中,其中variableName只是一些文本的名稱,可以有多個翻譯,並且它們對應於字符串的文化,如「en-US」 。因此,例如,我有一個變量「submitLogin」,它在登錄按鈕上顯示,我的數據庫中有三種語言:英語,德語和波蘭語。 (「submitLogin」,「en-US」,「英文翻譯),(」submitLogin「,」de-DE「,」德文翻譯「)和(」submitLogin「 」,‘PL-PL’,‘波蘭文翻譯’)MVC - 使用數據庫中的錯誤消息驗證屬性
到目前爲止,我的應用程序已經基於一類Resources.cs其中包含從數據庫中的所有翻譯變量,如:
public static string buttonContinueShopping {
get {
return (string) resourceProvider.GetResource("buttonContinueShopping", CultureInfo.CurrentUICulture.Name);
}
}
在意見我使用這些靜態屬性來獲得我的翻譯是這樣的:
@Resources.buttonContinueShopping
我可以創建一個動態類型,它會在視圖中的行爲方式完全相同(除了沒有靜態屬性,但我可以在每個視圖中創建一個對象,這不是問題 - 儘管看起來不錯不):
public class Resource : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
ResourceManager rsManager = new ResourceManager();
result = rsManager.GetString(binder.Name);
return true;
}
}
,但我有一個問題我的模特的屬性。到目前爲止,我已經使用他們這樣的:
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "errorRequired")]
[DataType(DataType.EmailAddress, ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "errorWrongDataType")]
[EmailAddress]
[Display(Name = "nameEmail", ResourceType = typeof(Resources.Resources))]
public string Email { get; set; }
現在我必須擺脫我Resources.cs的運行控制檯程序從數據庫中讀取轉換變量的所有唯一值,並創建屬性之後,因爲它們產生(就像我上面展示的那個)。我不能再有這個文件了,因爲用戶可以在運行時添加新的翻譯變量。
如何儘可能少地改變並使這些屬性讀取數據庫中的錯誤消息,顯示名稱等?
我有三個想法,但我不知道如何讓他們做:
使用自定義屬性 - 我試了必需的特性,但它只是不添加任何客戶端驗證,也不HTML中的任何錯誤消息。
使用自定義DataAnnotationsModelMetadataProvider - 我試過,但它不會重新加載頁面後工作 - 在第一頁加載存在的所有錯誤(尤其是這樣的:「字段的電子郵件是必需的。」),但重新加載頁面後,需要錯誤消息更改爲'字段是必需的'。這是我做:
public class CustomDataAnnotationsProvider: DataAnnotationsModelMetadataProvider { private ResourceManager resourceManager = new ResourceManager(); protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) { string key = string.Empty; string localizedValue = string.Empty; foreach (var attr in attributes) { if (attr != null) { if (attr is DisplayAttribute) { key = ((DisplayAttribute)attr).Name; if (!string.IsNullOrEmpty(key) && !key.Contains(" ")) { localizedValue = resourceManager.GetString(key); ((DisplayAttribute)attr).Name = localizedValue; } } else if (attr is ValidationAttribute || attr is RequiredAttribute) { key = ((ValidationAttribute)attr).ErrorMessage; if (!string.IsNullOrEmpty(key) && !key.Contains(" ")) { localizedValue = resourceManager.GetString(key); ((ValidationAttribute)attr).ErrorMessage = localizedValue; } } } } return base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
}
Global.asax中:
ModelMetadataProviders.Current = new CustomDataAnnotationsProvider();
型號:
[Required(ErrorMessage = "errorRequired")]
[EmailAddress(ErrorMessage = "errorWrongDataType")]
[Display(Name = "nameEmail")]
public string Email { get; set; }
使用反射(將是最好的但我不知道該怎麼做)。比方說,我離開我的屬性,並從我的Resources.cs中刪除所有屬性。現在RequiredAttribute是做什麼的?它需要給定的類型並獲得給定的屬性,例如它試圖做到這一點:
Resources.Resources.nameEmail.get
的問題是:是否有可能寫一些反射代碼,將採取非現有屬性(如nameEmail
)「請求」照顧?