我正在開發一個ASP.NET MVC 2項目,其中包含一些將元數據數據註解屬性應用於它們的業務實體(驗證屬性,顯示屬性等)。如何重新使用模型元數據來定製視圖模型?
喜歡的東西:
//User entity
public class User
{
[DisplayName("Vorname")]
[Required(ErrorMessage = "Vorname fehlt")]
[StringLength(MaxNameLength, ErrorMessage = "Vorname ist zu lang")]
public string FirstName { get; set; }
[DisplayName("Nachname")]
[Required(ErrorMessage = "Nachnamefehlt")]
[StringLength(MaxNameLength, ErrorMessage = "Nachname ist zu lang")]
public string LastName { get; set; }
[Required]
public string Password{ get; set; }
}
使用來自不同的看法元數據是沒有問題的,只要我使用我的業務實體的ViewModels或爲這樣的視圖模型的一部分:
//custom viewmodel with a user entity
public class CustomViewModel
{
public User{get;set;}
//some more properties...
}
但是,有時候我需要編寫一個視圖來編輯一些實體的一些字段,但不是所有字段。對於這些字段,我想重用已在我的用戶實體中指定的元數據。其他領域應該被忽略。我在談論像這樣的自定義視圖模型:
[MetadataType(typeof(User))]
public class UserNameViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
//no password on purpose, the user should only
//edit his first and last name in this view
}
這就是我遇到問題的地方。上面的自定義視圖模型在生成視圖時會導致異常,因爲它沒有密碼屬性。
類型相關聯的元數據類型 「Zeiterfassung.Models.ViewModels.Users.UserNameViewModel +的usermodel」 包含以下未知 屬性或字段:密碼。請確保 這些成員的名稱匹配 主要類型的 屬性的名稱。
此外,即使未發生此異常,我期望在表單提交時進行模型驗證時會遇到更多麻煩,因爲密碼在我的業務實體中被標記爲必需。
我可以想到幾個解決方法,但沒有一個看起來非常理想。在任何情況下,我都不能更改數據庫佈局,以便在上面的示例中密碼字段將位於單獨的實體中。
你將如何處理這種情況?
這就是我到目前爲止所做的,但它是很多重複的代碼(以元數據屬性的形式)。這也意味着必須爲幾個模型而不是僅僅一個模型單元測試驗證屬性,儘管本質上我只對所有模型具有相同的驗證規則(例如,總是需要FirstName)。 – 2010-10-19 12:11:22
只有在給定視圖的給定上下文中,驗證纔有意義,因此爲它編寫單元測試應該不成問題。如果使用真實模型而不是視圖模型,將會遇到的噩夢比將驗證屬性放在視圖模型上要差幾個數量級。你有沒有考慮使用其他框架進行驗證而不是數據註解? [FluentValidation](http://fluentvalidation.codeplex.com/)非常優秀,可以[單元測試](http://fluentvalidation.codeplex.com/wikipage?title=Testing&referringTitle=Documentation)。 – 2010-10-19 12:13:01
這不是一個很大的問題,但是它有很多額外的工作,主要是額外的單元測試。這也意味着更高的bug,因爲當我的業務模型上的驗證規則發生變化時,我也必須更新幾個視圖模型規則。在這個過程中很容易忘記其中的一個。 – 2010-10-19 12:17:18