浅谈ASP.NET MVC 3中如何使用Model
创始人
2024-07-20 20:01:08
0

昨天博客发了新文章,讲一下我对如何使用MVC中的Model的看法,不是什么大技术,当是一个技术讨论^^

原文地址:http://www.youguanbumen.net/Article.aspx?id=79

原文:

前两天写了个文章ASP.NET MVC 3 —— Model远程验证,主要记录了一下ASP.NET MVC 3中新增的RemoteAttribute类的使用,得益于这个类,我们可以在模型中为属性配置客户端远程校验的业务,文章中给了出一个简单的实体类MyUser_Add,举了一个最常见的注册用户时验证用户名是否存在的例子,最后成功地对用户名实现了用ajax加薪校验的功能。给出Model的代码如下:

  1. ///   
  2. /// 用户添加操作的模型  
  3. ///   
  4. publicclassMyUser_AddModel  
  5. {  
  6.     #region MyRegion  
  7.     ///   
  8.     /// 用户名  
  9.     ///   
  10.     [DisplayName("登录账号")]  
  11.     [Required(ErrorMessage = "用户账号不能为空")]  
  12.     [Remote("CheckUserAccountExists", "Test", ErrorMessage = "用户账号已存在")] 
  13. // 远程验证(Ajax)  
  14.     publicstringUserAccount { get; set; }  
  15. }   
  16.  
  17.       
  18.  

文章发到博客园上面之后有朋友提出一了一点:“这个我们可以认为在创建的时候解决重复问题,但是如果是Update的话,我相信这样的语句应该也会报错误的”。就是说如果这个Model用于做Update操作的时候,校验用户名是否存在的方法和Add操作会有点不同,因为要把自己排除在外,例如原来的用户名叫”user1“修改后还叫”user1“,这时候判断用户名是否存在的标准是”如果存在用户名是‘user1’的并且用户ID号不是当前这个要修改的用户,那么用户不可用(存在)“,而Add操作的时候不存在”自己“,所以我看可以理解为两个操作都需要判断用户名是否存在,但是使用了不同的策略!

刚好之前看了ASP.NET MVC 3自带的Demo(就是创建MVC3.0项目后生成的那个- -!),想写一下我自己认为的”微软希望我们怎么去设计MVC中的Model”的看法,发现似乎和这个问题有点联系,以下是我个人的观点:

首先我们看下Demo项目中Models目录下的AccountModels.cs,下面的代码摘自这个文件中的两个我认为很有代表性的类,都是和用户有关的,源代码如下:

  1. publicclassLogOnModel  
  2. {  
  3.     [Required]  
  4.     [Display(Name = "User name")]  
  5.     publicstringUserName { get; set; }  
  6.     [Required]  
  7.     [DataType(DataType.Password)]  
  8.     [Display(Name = "Password")]  
  9.     publicstringPassword { get; set; }  
  10.     [Display(Name = "Remember me?")]  
  11.     publicboolRememberMe { get; set; }  
  12. }  
  13. publicclassRegisterModel  
  14. {  
  15.     [Required]  
  16.     [Display(Name = "User name")]  
  17.     publicstringUserName { get; set; }  
  18.     [Required]  
  19.     [DataType(DataType.EmailAddress)]  
  20.     [Display(Name = "Email address")]  
  21.     publicstringEmail { get; set; }  
  22.     [Required]  
  23.     [ValidatePasswordLength]  
  24.     [DataType(DataType.Password)]  
  25.     [Display(Name = "Password")]  
  26.     publicstringPassword { get; set; }  
  27.     [DataType(DataType.Password)]  
  28.     [Display(Name = "Confirm password")]  
  29.     [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]  
  30.     publicstringConfirmPassword { get; set; }  
  31. }  

注意上面两个类的类名,我们很容易读懂一个是“(用户)登录模型”,一个是“(用户)注册模型”,有意思的地方在于两个类都用UserName、Password两个属性,UserName的验证方式完全一样,而Password有所不同,RegisterModel中多了一个ValidatePasswordLengthAttribute的特性——一个自定义验证特性。这两个模型对应的是不同的Action-View,于是我的理解是:Model是为了Actioin-View而存在的。例如,有一个页面是用来显示一张表单,这张表单会被提交到一个介绍Post请求的Action中,这时候就会创建一个和这个表单对应的Model,用来在View和Action中充当媒介的作用(所谓的“实体传参”)。

回到上面那个检测用户名是否存在的问题,基于这个想法可以得出一个解决方案,那就是创建另外一个新类,叫做MyUser_UpdateModel(用户修改模型),可以得出以下的代码

  1. publicclassMyUser_UpdateModel  
  2. {  
  3.     ///   
  4.     /// 用户名  
  5.     ///   
  6.     [DisplayName("登录账号")]  
  7.     [Required(ErrorMessage = "用户账号不能为空")]  
  8.     [ValidateUserAccountAttribute] // 自定义验证  
  9.     [Remote("CheckUserAccountExistsForUpdate", "Test", ErrorMessage = "用户账号已存在")] // 远程验证(Ajax)  
  10.     publicstringUserAccount { get; set; }  
  11. }  

注意到远程验证调用的是另外一个Action,这个Action的代码如下:

  1.  ///   
  2. /// 用于验证用户账号是否存在的Action(Update操作时使用)  
  3. ///   
  4. /// 用户账号  
  5. ///   
  6. [HttpGet]  
  7. public ActionResult CheckUserAccountExistsForUpdate(string UserAccount)  
  8. {  
  9.     var ms = ModelState;  
  10.     string[] existsUsers = { "wodanwojun" };  
  11.     bool exists = string.IsNullOrEmpty(existsUsers.FirstOrDefault(u => u.ToLower() == UserAccount.ToLower())) == false;  
  12.     return Json(!exists, JsonRequestBehavior.AllowGet);  
  13. }   
  14.  
  15.  
  16.    
  17.  
  18.     public class MyUser_UpdateModel  
  19.     {  
  20.         ///   
  21.         /// 用户名  
  22.         ///   
  23.         [DisplayName("登录账号")]  
  24.         [Required(ErrorMessage = "用户账号不能为空")]  
  25.         [ValidateUserAccountAttribute] // 自定义验证  
  26.         [Remote("CheckUserAccountExistsForUpdate", "Test", ErrorMessage = "用户账号已存在")] // 远程验证(Ajax)  
  27.         public string UserAccount { get; set; }  
  28.     } 

这里假设要修改的用户的用户名叫做“youguanbumen”,所以验证的时候如果输入了有关部门是不应该提示“该账号已存在”的(因为就是他自己,用了这个账号是没问题的)。控制器的代码我就不写咯,大致就是得到一个用户名叫做“youguanbumen”的Model——MyUser_UpdateModel类,然后通过return View(object model)方法丢给View(当然,View是强类型的——MyUser_UpdateModel类),测试结果截图如下:

1、输入“wodanwojun”作为用户名,发现通不过,就像下面这张截图这样,原因请见上面的代码!

2、输入“youguanbumen”作为用户名。发现没有错误提示,就像下面这张截图这样,原因请见上面的代码,并对照前一篇文章中另外一个用于远程校验的Action的代码!

总结一下:似乎写出来的每一篇文章都不短但是讲的东西都很少,呵呵,请别介意^_^。虽然写代码的经验很不多,但是个人对于代码还是有一些自己的看法的。选择一个框架来开发一个系统,就意味着在开发的过程中你需要遵循某些约定好的东西,例如选择WebForm来开发系统,就尽量的接受”事件相应“和服务器端控件;选择了MVC就要接受把C#代码嵌到页面去的这个事实,当然如果使用了某些RIA框架后可能不出现这种情况(因为页面上的东西基本都是异步请求回来的)。特别是多人开发的时候,我们有必要遵循某些套路来写代码,例如上面这个例子,也许写Model、写View和写Action是三个不同的人来完成的时候,“如果遵循这一个Action会有一个Model来支持它”的这种套路来走的话,每个人都很容易找到代码的下手点,写View的人知道如何去声明页面为强类型(他会去找相关的Model),写Action的人知道return View(object model)中的model是啥,也知道用于处理Post的Action的参数是什么,写Model的人需要很了解业务,知道哪些字段是必填的,那些字段有长度限制等等,但是他也许不知道这个Model会被拿去怎么展示!

ASP.NET MVC中的Model是和业务紧密相关的,有什么样的业务需求就会产生什么样的Model,并且会有相应的Action来出来它,有相应的View来展示它。如果基于这个想法来开发系统的话,很有可能得出这样一个简要的开发流程:研究业务-->转化为对应的Model,根据业务需求对Model的属性配置验证特性-->设计数据库表来对数据进行存放(也许是xml也不一定)-->设计View来展示它,设计Action来处理它......。

原文链接:http://www.cnblogs.com/serafin/archive/2011/01/27/1945934.html

 

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...