MVC開發應用程序有個問題,很多開發者不知如何去使用頁面模型,大多數開發者認為為每一個頁面去設計一個實體是多余的,所以他們使用數據庫實體來代碼頁面視圖模型,事實上,這樣做的好處就是節省的代碼,但不好的地方是什么呢?我來總結一下吧:
1 方便根據每一種業務邏輯和前台頁面表現,去對模型進行特性的設置
2 前台UI部分與業務層與數據庫層可以更加獨立,前台頁面模型並不依賴於數據庫模型
3 可以根據具體業務,去分別設置它們的驗證及約束關系
好了,上面我說了3點不使用viewModel的缺點,事實上,確實是這樣的,比如,你的userbase實體,如果它需要提供兩種業務,如“登陸”和“注冊”,那么它的前台信息展現與驗證業務肯定是不相同的,這時,如果使用ViewModel就很容易的解決了這個問題。
以下是用戶模型的代碼片斷
1 /// <summary> 2 /// 用戶登陸視圖模型 3 /// </summary> 4 public class UserBaseLogOnModel 5 { 6 [Required] 7 [Display(Name = "用戶名")] 8 public string Name { get; set; } 9 [Required] 10 [DataType(DataType.Password)] 11 [Display(Name = "密碼")] 12 public string Password { get; set; } 13 [Required] 14 [Display(Name = "真實姓名")] 15 public string RealName { get; set; } 16 } 17 /// <summary> 18 /// 用戶注冊模型 19 /// </summary> 20 public class UserBaseRegisterModel 21 { 22 [Required] 23 [Display(Name = "用戶名")] 24 public string Name { get; set; } 25 [Required] 26 [DataType(DataType.Password)] 27 [Display(Name = "密碼")] 28 public string Password { get; set; } 29 [Required] 30 [DataType(DataType.Password)] 31 [Display(Name = "密碼")] 32 [Compare("Password", ErrorMessage = "新密碼和確認密碼不匹配。")] 33 public string ConfirmPassword { get; set; } 34 [Required] 35 [Display(Name = "真實姓名")] 36 public string RealName { get; set; } 37 [Required] 38 [DataType(DataType.EmailAddress)] 39 [Display(Name = "電子郵件")] 40 public string Email { get; set; } 41 [Required] 42 [DataType(DataType.PhoneNumber)] 43 [Display(Name = "電話")] 44 public string Tel { get; set; } 45 [Required] 46 [Display(Name = "證件類型")] 47 public SelectList IDType { get; set; } 48 [Required] 49 [Display(Name = "證件號碼")] 50 public string IDNumber { get; set; } 51 }
有了視圖模型,那我們如何去使用它呢,我們以用戶登陸為例,來說一下吧:
首先,我們定義的ViewModel里的屬性,要求和數據模型中的屬性名稱相同,這樣方便進行模型之間的賦值,用戶登陸與用戶注冊都是與userbase表相關的,
所以,在HTTPPost指向的方法時,參數可以就是UserBase類型的,看代碼:
1 [HttpPost] 2 public ActionResult LogOn(UserBases entity) 3 { 4 }
而如果它們的屬性名稱是相同的,MVC表單在進行POST請求時,可以把屬性信息自動填充到參數實例上去,但如果你的模型中包括了導航屬性(其它關系表的實例),則需要手動為它進行初始化,如代碼:
1 [HttpPost] 2 public ActionResult LogOn(UserBases entity) 3 { 4 entity.User_Extensions_Extend = new User_Extensions(); 5 TryUpdateModel(entity.User_Extensions_Extend);//填充模型 6 }
當我們從表單中把數據得到后,要做的是什么呢?“驗證”,我們需要知道表單中填寫的內容是否是符合我們設定的規范,如果不符合,則返回錯誤信息。
1 [HttpPost] 2 public ActionResult LogOn(UserBases entity) 3 { 4 entity.User_Extensions_Extend = new User_Extensions(); 5 TryUpdateModel(entity.User_Extensions_Extend);//填充模型 6 if (ModelState.IsValid) 7 { 8 VM = iUserRepository.Login(entity); 9 if (VM.IsComplete) 10 return RedirectToAction("Index", "Home"); 11 else 12 VM.ToList().ForEach(i => ModelState.AddModelError("", i)); 13 14 } 15 return View(); 16 }
在代碼中,我們並沒有出現頁面中需要的視力模型,它是如何與實體模型轉換的呢,事實上,它們之間並沒有發生轉換,只是表單與實體之間發生了賦值而以,即
只要實體模型與視圖模型的屬性名相同,就完成可以使用MVC的自動賦值功能(TryUpdateModel)。