爱上MVC3系列~使用视图模型的好处及与数据模型之间的赋值问题
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)。