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

使用Visual Studio 2010和MVC 2.0增強(qiáng)驗(yàn)證功能

開發(fā) 后端
本篇文章主要關(guān)注使用DataAnnotations來對(duì)model進(jìn)行驗(yàn)證,同時(shí)會(huì)對(duì)最新版本特性進(jìn)行簡(jiǎn)單的接觸,以及如何使用Visual Studio 2010和MVC 2.0增強(qiáng)驗(yàn)證功能。

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

如果將驗(yàn)證代碼放到一個(gè)集中的地方時(shí),那類似上面所說的改變會(huì)不會(huì)變得更簡(jiǎn)單些?Model中的DataAnnotations正是為此而來,在MVC 2.0中,這一特性被包含在內(nèi)。

DataAnnotations作為.net Framework的一部分已經(jīng)有一段時(shí)間了,但是MVC 2.0中增加了ModelMetaData類,這是儲(chǔ)存MetaData的容器,默認(rèn)會(huì)使用同樣也是新增類的DataAnnotationsMetaDataProvider類。因?yàn)閭魅氲闹禃?huì)由Action方法接受model binding作為匹配傳入?yún)?shù)和action的參數(shù)而介入。

在MVC 2.0中,默認(rèn)的model binder使用DataAnnotationsMetaDataProvider來獲取metadata中model binder嘗試匹配的對(duì)象,如果驗(yàn)證用的metadata存在,則其會(huì)通過對(duì)對(duì)象的屬性和傳入的值比較來進(jìn)驗(yàn)證,這類meta由你通過使用標(biāo)簽(Attribute)修飾屬性來實(shí)現(xiàn)。

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

  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. }  

下面,我在為屬性添加一些標(biāo)簽(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. }  

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

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

  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. }  

很簡(jiǎn)單是吧,這個(gè)類繼承了ValidationAttribute并重寫了IsValid()虛方法,如果未提供值,或是值小于當(dāng)前日期(DateTime.Now),則返回True.利用標(biāo)簽(Attribute)的方式讓在一個(gè)集中的地方應(yīng)用驗(yàn)證規(guī)則變得簡(jiǎn)單,現(xiàn)在,只要ContactPersonViewModel在程序中被用到了,則驗(yàn)證規(guī)則同時(shí)也會(huì)被應(yīng)用到。但現(xiàn)在DefaultModelBinder內(nèi)的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. <% } %>  

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

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

  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屬性,因?yàn)樵诎崖?lián)系人添加到數(shù)據(jù)庫(kù)以前并不會(huì)存在id屬性,而去掉Type屬性是因?yàn)樵赩iewModel中它的類型是SelectList,但在BLL層中ContactPerson對(duì)象中卻是枚舉類型,如果ModelState的IsValid屬性為True(注:既驗(yàn)證通過),則ViewModel的屬性會(huì)和ContactPerson對(duì)象的屬性進(jìn)行匹配,如果IsValid不為True,數(shù)據(jù)會(huì)回傳到View中顯示驗(yàn)證失敗的相關(guān)信息。

上面代碼中我們注意到了Request.Form[“Type”]這個(gè)string類型的ParseEnum<T>擴(kuò)展方法,這也是為什么我去掉Type屬性,只有這樣它才會(huì)被轉(zhuǎn)換為適當(dāng)?shù)念愋汀U(kuò)展方法的原型(在我的Google Analytics 文中)如下:

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

這個(gè)action方法也是如此,除了對(duì)DateOfBirth進(jìn)行編輯那部分:

  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>擴(kuò)展方法,而是使用了EditorFor<T>方法,默認(rèn)情況下,DateTime類型都以hh:mm:ss這樣的方式顯示,但我并不喜歡這種格式,所以我創(chuàng)建了一個(gè)格式化顯示時(shí)間日期的模板,在View/Shared目錄下,我添加了一個(gè)名為EditorTemplates(這也是MVC中應(yīng)有命名方式,因?yàn)镸VC會(huì)自動(dòng)搜索這個(gè)位置)并在此目錄下添加一個(gè)名為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) %> 

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

總結(jié)

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

Visual Studio 2010 全球發(fā)布會(huì)

【編輯推薦】

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

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歷史調(diào)試功能

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-26 09:26:04

Visual Stud

2009-08-21 13:29:20

Visual Stud

2009-11-10 13:43:37

Visual Stud

2009-11-19 10:55:33

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
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 狠狠爱免费视频 | 亚洲精品在线看 | 日韩视频在线一区 | 国产精品免费一区二区三区 | 欧美一区二区三区国产精品 | 国产精品久久久久久吹潮日韩动画 | 成人在线精品视频 | 欧美日韩在线精品 | 亚洲精品国产一区 | www.日韩av.com| 国产精品爱久久久久久久 | www4虎| 国产精品免费观看 | 久久岛国| 久久久久久久国产 | 国产高清在线 | 久久久国产一区二区三区 | 国产精品美女在线观看 | 中文字字幕一区二区三区四区五区 | 午夜寂寞影院在线观看 | 日本久久视频 | 日韩在线播放中文字幕 | 欧美成人a| 国产日产精品一区二区三区四区 | 色久影院 | www免费视频| 91精品在线观看入口 | 国产成人在线一区 | 曰批视频在线观看 | 精品国产18久久久久久二百 | 99热热热热 | 日一区二区 | 国产精品成人久久久久 | 亚洲图片一区二区三区 | 日本一区高清 | 99精品久久久 | 先锋影音资源网站 | 精品av| 九九九精品视频 | 欧美日韩久久久 | jlzzjlzz国产精品久久 |