成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用Visual Studio 2010和MVC 2.0增強驗證功能

開發 后端
本篇文章主要關注使用DataAnnotations來對model進行驗證,同時會對最新版本特性進行簡單的接觸,以及如何使用Visual Studio 2010和MVC 2.0增強驗證功能。

在開始之前,我不得不說明我已經安裝了Visual Studio 2010 RC1,并使用它將老版本轉換為ASP.Net 4.0,大多數情況下,當你接收到來自用戶從form表單post來的信息后,你的驗證代碼往往會檢查相應的值是否存在,數據類型是否正確以及數據的范圍是否正確。

如果將驗證代碼放到一個集中的地方時,那類似上面所說的改變會不會變得更簡單些?Model中的DataAnnotations正是為此而來,在MVC 2.0中,這一特性被包含在內。

DataAnnotations作為.net Framework的一部分已經有一段時間了,但是MVC 2.0中增加了ModelMetaData類,這是儲存MetaData的容器,默認會使用同樣也是新增類的DataAnnotationsMetaDataProvider類。因為傳入的值會由Action方法接受model binding作為匹配傳入參數和action的參數而介入。

在MVC 2.0中,默認的model binder使用DataAnnotationsMetaDataProvider來獲取metadata中model binder嘗試匹配的對象,如果驗證用的metadata存在,則其會通過對對象的屬性和傳入的值比較來進驗證,這類meta由你通過使用標簽(Attribute)修飾屬性來實現。

下面例子中我通過原程序中添加聯系人這一過程來描述使用DataAnnotatioins的方法,這里我們使用自定義ViewModel,名為:ContactPersonViewModel。通過Contact.Add()這個action方法來添加聯系人,代碼如下:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Web.Mvc;  
  4. using System.ComponentModel;  
  5.  
  6. namespace ContactManagerMVC.Views.ViewModels  
  7. {  
  8.   public class ContactPersonViewModel  
  9.   {  
  10.     public int Id { get; set; }  
  11.     public string FirstName { get; set; }  
  12.     public string MiddleName { get; set; }  
  13.     public string LastName { get; set; }  
  14.     public DateTime DateOfBirth { get; set; }  
  15.     public IEnumerable<SelectListItem> Type { get; set; }  
  16.   }  
  17. }  

下面,我在為屬性添加一些標簽(Attribute):

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Web.Mvc;  
  4. using System.ComponentModel.DataAnnotations;  
  5. using ContactManagerMVC.Attributes;  
  6. using System.ComponentModel;  
  7.  
  8. namespace ContactManagerMVC.Views.ViewModels  
  9. {  
  10.   public class ContactPersonViewModel  
  11.   {  
  12.     public int Id { get; set; }  
  13.     [Required(ErrorMessage = "Please provide a First Name!")]  
  14.     [StringLength(25, ErrorMessage = "First name must be less than 25 characters!")]  
  15.     [DisplayName("First Name")]  
  16.     public string FirstName { get; set; }  
  17.  
  18.     [DisplayName("Middle Name")]  
  19.     public string MiddleName { get; set; }  
  20.  
  21.     [Required(ErrorMessage = "Please provide a Last Name!")]  
  22.     [StringLength(25, ErrorMessage = "Last name must be less than 25 characters!")]  
  23.     [DisplayName("Last Name")]  
  24.     public string LastName { get; set; }  
  25.  
  26.     [Required(ErrorMessage = "You must provide a Date Of Birth!")]  
  27.     [BeforeTodaysDate(ErrorMessage = "You can't add someone who hasn't been born yet!")]  
  28.     [DisplayName("Date Of Birth")]  
  29.     public DateTime? DateOfBirth { get; set; }  
  30.  
  31.     public IEnumerable<SelectListItem> Type { get; set; }  
  32.   }  
  33. }  

上面標簽的絕大多數標簽都是在System.ComponentModel.Annotations命名空間內,只有RequiredAttribute標簽不在此命名空間內,這個標簽聲明此值必須是一個有效值,并且包含ErrorMessage屬性。這個屬性可以讓你傳入自定義錯誤信息。StringLengthAttribute標簽指定了屬性可以接受的最小值和***值范圍。當和RequiredAttribute標簽結合使用時,只需要設置可以接受的***值。DisplayNameAttribute用于設置屬性如何顯示。#p#

上面標簽中BeforeTodaysDateAttribute標簽并不是.net Framework所提供,這是一個自定義標簽,用于檢測日期是否比當前的日期要早,你可以看到ErrorMessage值被設置。這個標簽用于防止任何被添加到聯系人列表的聯系人還未出生,下面是這個標簽的代碼:

  1. using System.ComponentModel.DataAnnotations;  
  2. using System;  
  3.  
  4. namespace ContactManagerMVC.Attributes  
  5. {  
  6.   public class BeforeTodaysDateAttribute : ValidationAttribute  
  7.   {  
  8.     public override bool IsValid(object value)  
  9.     {  
  10. if (value == null)  
  11. {  
  12.   return true;  
  13. }  
  14. DateTime result;  
  15. if (DateTime.TryParse(value.ToString(), out result))  
  16. {  
  17.   if (result < DateTime.Now)  
  18.   {  
  19.     return true;  
  20.   }  
  21. }  
  22. return false;  
  23.     }  
  24.   }  
  25. }  

很簡單是吧,這個類繼承了ValidationAttribute并重寫了IsValid()虛方法,如果未提供值,或是值小于當前日期(DateTime.Now),則返回True.利用標簽(Attribute)的方式讓在一個集中的地方應用驗證規則變得簡單,現在,只要ContactPersonViewModel在程序中被用到了,則驗證規則同時也會被應用到。但現在DefaultModelBinder內的DataAnnotations被支持,下面來看新版本的Add Partial View:

  1. <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactPersonViewModel>" %> 
  2.  
  3. <script type="text/javascript"> 
  4.   $(function() {  
  5.   $('#DateOfBirth').datepicker({ dateFormat: 'yy/mm/dd' });  
  6.   });  
  7.   $('#save').click(function () {  
  8. $.ajax({  
  9.     type: "POST",  
  10.     url: $("#AddContact").attr('action'),  
  11.     data: $("#AddContact").serialize(),  
  12.     dataType: "text/plain",  
  13.     success: function (response) {  
  14.   if (response == "Saved") {  
  15. window.location = "/";   
  16.   }else {  
  17. $("#details").html(response);  
  18.   }  
  19.     }  
  20. });  
  21.   });  
  22. </script> 
  23.  
  24. <% using (Html.BeginForm("Add", "Contact", FormMethod.Post, new { id = "AddContact" }))  
  25.    {%> 
  26. <table> 
  27.   <tr> 
  28. <td class="LabelCell"><%= Html.LabelFor(m => m.FirstName)%> </td> 
  29. <td><%= Html.TextBox(m => m.FirstName)%>   
  30. <%= Html.ValidationMessageFor(m => m.FirstName)%></td>    
  31.   </tr> 
  32.   <tr> 
  33. <td class="LabelCell"><%= Html.LabelFor(m => m.MiddleName)%> </td> 
  34. <td><%= Html.TextBox(m => m.MiddleName)%></td>    
  35.   </tr> 
  36.   <tr> 
  37. <td class="LabelCell"><%= Html.LabelFor(m => m.LastName)%> </td> 
  38. <td><%= Html.TextBox(m => m.LastName)%>   
  39. <%= Html.ValidationMessageFor(m => m.LastName)%></td>    
  40.   </tr> 
  41.   <tr> 
  42. <td class="LabelCell"><%= Html.LabelFor(m => m.DateOfBirth)%> </td> 
  43. <td><%= Html.TextBox(m => m.DateOfBirth)%>   
  44. <%= Html.ValidationMessageFor(m => m.DateOfBirth)%></td>    
  45.   </tr> 
  46.   <tr> 
  47.     <td class="LabelCell"><%= Html.LabelFor(m => m.Type)%></td> 
  48.     <td><%= Html.DropDownList("Type")%> 
  49.     </td> 
  50.   </tr> 
  51.   <tr> 
  52.     <td class="LabelCell"></td> 
  53.     <td><input type="button" name="save" id="save" value="Save" /></td> 
  54.   </tr> 
  55. </table> 
  56. <% } %>  

可以看出,這里使用新的強類型Html Helper.對前面項目修改的兩處是利用了jQuery代碼。***處是添加聯系人的Partial View是通過AJax提交,如果驗證失敗,則添加的form會再次被顯示,如果驗證通過,新的聯系人被添加到列表中,頁面會刷新繼而顯示更新后包含新聯系人的列表。

由于下面幾種原因,原來的Action方法需要被修正。首先修改action方法使其接受ContactPersonViewModel而不是ContactPerson作為參數,這是因為相關的驗證規則應用于ContactPersonViewModel,如果不將參數類型改變,那model binder依然能將傳入的值和ContactPerson的屬性相匹配,但所有的驗證規則就不復存在了。第二個改變是檢查ModelState的IsValid屬性是否有效,否則整個驗證就變得毫無意義.

  1. [AcceptVerbs(HttpVerbs.Post)]  
  2. public ActionResult Add([Bind(Exclude = "Id, Type")]ContactPersonViewModel person)  
  3. {  
  4.  
  5.     if (ModelState.IsValid)  
  6.     {  
  7.   var p = new ContactPerson  
  8.   {  
  9. FirstName = person.FirstName,  
  10. MiddleName = person.MiddleName,  
  11. LastName = person.LastName,  
  12. Type = Request.Form["Type"].ParseEnum<PersonType>()  
  13.   };  
  14.   if (person.DateOfBirth != null)  
  15. p.DateOfBirth = (DateTime)person.DateOfBirth;  
  16.   ContactPersonManager.Save(p);  
  17.   return Content("Saved");  
  18.     }  
  19.     var personTypes = Enum.GetValues(typeof(PersonType))  
  20.     .Cast<PersonType>()  
  21.     .Select(p => new  
  22.     {  
  23.   ID = p,  
  24.   Name = p.ToString()  
  25.     });  
  26.     person.Type = new SelectList(personTypes, "ID", "Name");  
  27.     return PartialView(person);  
  28. }   
  29.  

在model綁定過程中,我去掉了id和Type屬性,因為在把聯系人添加到數據庫以前并不會存在id屬性,而去掉Type屬性是因為在ViewModel中它的類型是SelectList,但在BLL層中ContactPerson對象中卻是枚舉類型,如果ModelState的IsValid屬性為True(注:既驗證通過),則ViewModel的屬性會和ContactPerson對象的屬性進行匹配,如果IsValid不為True,數據會回傳到View中顯示驗證失敗的相關信息。

上面代碼中我們注意到了Request.Form[“Type”]這個string類型的ParseEnum<T>擴展方法,這也是為什么我去掉Type屬性,只有這樣它才會被轉換為適當的類型。擴展方法的原型(在我的Google Analytics 文中)如下:

  1. public static T ParseEnum<T>(this string token)  
  2. {  
  3.     return (T)Enum.Parse(typeof(T), token);  
  4. }  
  5.  
  6. edit  

這個action方法也是如此,除了對DateOfBirth進行編輯那部分:

  1. <tr> 
  2.   <td class="LabelCell"><%= Html.LabelFor(m => m.DateOfBirth)%> </td> 
  3.   <td><%= Html.EditorFor(m => m.DateOfBirth)%>   
  4. <%= Html.ValidationMessageFor(m => m.DateOfBirth)%></td>    
  5. </tr>  

這里我并沒有使用TextBoxFor<T>擴展方法,而是使用了EditorFor<T>方法,默認情況下,DateTime類型都以hh:mm:ss這樣的方式顯示,但我并不喜歡這種格式,所以我創建了一個格式化顯示時間日期的模板,在View/Shared目錄下,我添加了一個名為EditorTemplates(這也是MVC中應有命名方式,因為MVC會自動搜索這個位置)并在此目錄下添加一個名為DateTime的Partial View,這也是MVC的慣例,而DateTime.ascx的代碼如下:

  1. <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %> 
  2. <%= Html.TextBox("", Model.HasValue ? Model.Value.ToShortDateString() : string.Empty) %> 

雖然只有短短兩行代碼,但是可以讓時間日期如果為空時,什么都不顯示,而如果時間存在,則以ShortDate的格式顯示。

總結

本篇文章研究了ASP.Net MVC 2.0中利用DataAnnotations來進行驗證,現在這已經是.net framework的一部分。文中還簡單的接觸了新版本中的一些特性,包括強類型的HTML Helper以及模板。本篇文章的代碼使用Visual Studio 2010 RC1創建的,所以代碼不能在VWD和Visual Studio的環境中調試。

Visual Studio 2010 全球發布會

【編輯推薦】

  1. 升級Visual Studio 2010和.Net 4注意要點
  2. 專家揭秘Visual Basic 2010的十大新特性
  3. Visual Studio 2010 Ultimate中MSF過程模型設計
  4. Visual Studio 2010代碼編譯器特性分析
  5. 詳解Visual Studio 2010五大新特性
責任編輯:王曉東 來源: 博客園
相關推薦

2010-02-26 09:18:24

Visual Stud

2010-04-12 08:43:45

Visual Stud

2023-09-26 00:24:44

VisualStudio視圖

2009-04-23 14:05:28

Visual Stud歷史調試功能

2009-10-22 09:47:33

Visual Stud

2009-03-17 08:56:57

Visual StudVS2010C++

2010-09-25 08:50:00

Visual Stud

2009-12-02 09:43:38

Visual Stud

2009-08-21 13:29:20

Visual Stud

2009-08-26 09:26:04

Visual Stud

2009-11-19 10:55:33

Visual Stud

2009-11-10 13:43:37

Visual Stud

2010-03-16 14:32:16

Visual Stud

2009-11-19 09:59:47

Visual Stud

2009-12-02 10:44:30

Visual Stud

2010-04-15 08:40:00

UML建模Visual Stud

2009-12-01 19:12:41

Visual Stud

2010-02-23 10:39:43

Visual Stud

2009-10-19 09:48:24

Visual Stud

2010-02-04 09:17:26

Visual Stud
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产 日韩 欧美 在线 | 99精品视频免费观看 | 一区二区在线免费观看视频 | 亚洲一区日韩 | 久久久久久综合 | 亚洲狠狠| 成人片在线看 | 九一视频在线观看 | 国产精品久久久久久久久久久久冷 | 日本一区二区三区免费观看 | 国产日产久久高清欧美一区 | 婷婷五月色综合 | 日韩毛片免费视频 | 雨宫琴音一区二区在线 | 精品国产不卡一区二区三区 | 国产www.| 99精品欧美一区二区三区 | 国产亚洲一区二区精品 | 欧美色人 | 免费在线成人 | 欧美色视频免费 | 日韩伦理一区二区 | 国产视频1 | 日韩视频一区二区 | 亚洲精品中文字幕在线观看 | 亚洲在线一区二区 | 国产一级成人 | av激情在线 | 国产一区在线看 | 91激情视频| 日本天天操 | 日韩成人在线电影 | 久久出精品 | 成人在线免费视频观看 | 亚洲精品www. | 国产精品一区视频 | 亚洲一区播放 | 国产在线精品一区二区 | 日韩一区二区三区在线 | 国产精品一区二区视频 | 日本一道本视频 |