麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > .NET > 正文

ASP.NET MVC的四種驗證編程方式

2024-07-10 13:29:28
字體:
來源:轉載
供稿:網(wǎng)友

ASP.NET MVC采用Model綁定為目標Action生成了相應的參數(shù)列表,但是在真正執(zhí)行目標Action方法之前,還需要對綁定的參數(shù)實施驗證以確保其有效性,我們將針對參數(shù)的驗證成為Model綁定,需要的朋友可以參考下

我們可以采用4種不同的編程模式來進行針對綁定參數(shù)的驗證。

一、手工驗證綁定的參數(shù)

在定義具體Action方法的時候,對已經(jīng)成功綁定的參數(shù)實施手工驗證無疑是一種最為直接的編程方式,接下來我們通過一個簡單的實例來演示如何將參數(shù)驗證邏輯實現(xiàn)在對應的Action方法中,并在沒有通過驗證的情況下將錯誤信息響應給客戶端。我們在一個ASP.NET MVC應用中定義了如下一個Person類作為被驗證的數(shù)據(jù)類型,它的Name、Gender和Age三個屬性分別表示一個人的姓名、性別和年齡。

 

 
  1. public class Person  
  2. {  
  3. [DisplayName("姓名")]  
  4. public string Name { get; set; }  
  5.  
  6. [DisplayName("性別")]  
  7. public string Gender { get; set; }  
  8.  
  9. [DisplayName("年齡")]  
  10. public int? Age { get; set; }  
  11. }  

接下來我們定義了如下一個HomeController。在針對GET請求的Action方法Index中,我們創(chuàng)建了一個Person對象并將其作為Model呈現(xiàn)在對應的View中。另一個支持POST請求的Index方法具有一個Person類型的參數(shù),我們在該Action方法中先調(diào)用Validate方法對這個輸入?yún)?shù)實施驗證。如果驗證成功(ModeState.IsValid屬性返回True),我們返回一個內(nèi)容為“輸入數(shù)據(jù)通過驗證”的ContentResult,否則將此參數(shù)作為Model呈現(xiàn)在對應的View中。

 

 
  1. public class HomeController : Controller  
  2. {  
  3. [HttpGet]  
  4. public ActionResult Index()  
  5. {  
  6. return View(new Person());  
  7. }  
  8.  
  9. [HttpPost]  
  10. public ActionResult Index(Person person)  
  11. {  
  12. Validate(person);  
  13.  
  14. if (!ModelState.IsValid)  
  15. {  
  16. return View(person);  
  17. }  
  18. else 
  19. {  
  20. return Content("輸入數(shù)據(jù)通過驗證");  
  21. }  
  22. }  
  23.  
  24. private void Validate(Person person)  
  25. {  
  26. if (string.IsNullOrEmpty(person.Name))  
  27. {  
  28. ModelState.AddModelError("Name""'Name'是必需字段");  
  29. }  
  30.  
  31. if (string.IsNullOrEmpty(person.Gender))  
  32. {  
  33. ModelState.AddModelError("Gender""'Gender'是必需字段");  
  34. }  
  35. else if (!new string[] { "M""F" }.Any(  
  36. g => string.Compare(person.Gender, g, true) == 0))  
  37. {  
  38. ModelState.AddModelError("Gender",  
  39. "有效'Gender'必須是'M','F'之一");  
  40. }  
  41.  
  42. if (null == person.Age)  
  43. {  
  44. ModelState.AddModelError("Age""'Age'是必需字段");  
  45. }  
  46. else if (person.Age > 25 || person.Age < 18)  
  47. {  
  48. ModelState.AddModelError("Age""有效'Age'必須在18到25周歲之間");  
  49. }  
  50. }  
  51. }  

如上面的代碼片斷所示,我們在Validate該方法中我們對作為參數(shù)的Person對象的3個屬性進行逐條驗證,如果提供的數(shù)據(jù)沒有通過驗證,我們會調(diào)用當前ModelState的AddModelError方法將指定的驗證錯誤消息轉換為ModelError保存起來。我們采用的具體的驗證規(guī)則如下。

Person對象的Name、Gender和Age屬性均為必需字段,不能為Null(或者空字符串)。

表示性別的Gender屬性的值必需是“M”(Male)或者“F”(Female),其余的均為無效值。

Age屬性表示的年齡必須在18到25周歲之間。

如下所示的是Action方法Index對應View的定義,這是一個Model類型為Person的強類型View,它包含一個用于編輯人員信息的表單。我們直接調(diào)用HtmlHelper 的擴展方法EditorForModel將作為Model的Person對象以編輯模式呈現(xiàn)在表單之中。

 

 
  1. @model Person  
  2. <html>  
  3. <head>  
  4. <title>編輯人員信息</title>  
  5. </head>  
  6. <body>  
  7. @using (Html.BeginForm())  
  8. {  
  9. @Html.EditorForModel()  
  10. <input type="submit" value="保存"/>  
  11. }  
  12. </body>  
  13. </html>  

直接運行該程序后,一個用于編輯人員基本信息的頁面會被呈現(xiàn)出來,如果我們在輸入不合法的數(shù)據(jù)并提交后,相應的驗證信息會以圖1所示的形式呈現(xiàn)出來。

二、使用ValidationAttribute特性

將針對輸入?yún)?shù)的驗證邏輯和業(yè)務邏輯定義在Action方法中并不是一種值得推薦的編程方式。在大部分情況下,同一個數(shù)據(jù)類型在不同的應用場景中具有相同的驗證規(guī)則,如果我們能將驗證規(guī)則與數(shù)據(jù)類型關聯(lián)在一起,讓框架本身來實施數(shù)據(jù)驗證,那么最終的開發(fā)者就可以將關注點更多地放在業(yè)務邏輯的實現(xiàn)上面。實際上這也是ASP.NET MVC的Model驗證系統(tǒng)默認支持的編程方式。當我們在定義數(shù)據(jù)類型的時候,可以在類型及其數(shù)據(jù)成員上面應用相應的ValidationAttribute特性來定義默認采用的驗證規(guī)則。

“System.ComponentModel.DataAnnotations”命名空間定義了一系列具體的ValidationAttribute特性類型,它們大都可以直接應用在自定義數(shù)據(jù)類型的某個屬性上對目標數(shù)據(jù)成員實施驗證。這些預定義驗證特性不是本章論述的重點,我們會在“下篇”中對它們作一個概括性的介紹。

常規(guī)驗證可以通過上面列出的這些預定義ValidationAttribute特性來完成,但是在很多情況下我們需要通過創(chuàng)建自定義的ValidationAttribute特性來解決一些特殊的驗證。比如上面演示實例中針對Person對象的驗證中,我們要求Gender屬性指定的表示性別的值必須是“M/m”和“F/f”兩者之一,這樣的驗證就不得不通過自定義的ValidationAttribute特性來實現(xiàn)。

針對 “某個值必須在指定的范圍內(nèi)”這樣的驗證規(guī)則,我們定義一個DomainAttribute特性。如下面的代碼片斷所示,DomainAttribute具有一個IEnumerable類型的只讀屬性Values提供了一個有效值列表,該列表在構造函數(shù)中被初始化。具體的驗證實現(xiàn)在重寫的IsValid方法中,如果被驗證的值在這個列表中,則視為驗證成功并返回True。為了提供一個友好的錯誤消息,我們重寫了方法FormatErrorMessage。

 

  1. [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]  
  2. public class DomainAttribute : ValidationAttribute  
  3. {  
  4. public IEnumerable<string> Values { get; private set; }  
  5.  
  6. public DomainAttribute(string value)  
  7. {  
  8. this.Values = new string[] { value };  
  9. }  
  10.  
  11. public DomainAttribute(params string[] values)  
  12. {  
  13. this.Values = values;  
  14. }  
  15.  
  16. public override bool IsValid(object value)  
  17. {  
  18. if (null == value)  
  19. {  
  20. return true;  
  21. }  
  22. return this.Values.Any(item => value.ToString() == item);  
  23. }  
  24.  
  25. public override string FormatErrorMessage(string name)  
  26. {  
  27. string[] values = this.Values.Select(value => string.Format("'{0}'", value)).ToArray();  
  28. return string.Format(base.ErrorMessageString, name,string.Join(",", values));  
  29. }  
  30. }  

由于ASP.NET MVC在進行參數(shù)綁定的時候會自動提取應用在目標參數(shù)類型或者數(shù)據(jù)成員上的ValidationAttribute特性,并利用它們對提供的數(shù)據(jù)實施驗證,所以我們不再需要像上面演示的實例一樣自行在Action方法中實施驗證,而只需要在定義參數(shù)類型Person的時候應用相應的ValidationAttribute特性將采用的驗證規(guī)則與對應的數(shù)據(jù)成員相關聯(lián)。

如下所示的是屬性成員上應用了相關ValidationAttribute特性的Person類型的定義。我們在三個屬性上均應用了RequiredAttribute特性將它們定義成必需的數(shù)據(jù)成員,Gender和Age屬性上則分別應用了DomainAttribute和RangeAttribute特性對有效屬性值的范圍作了相應限制。

 

 
  1. public class Person  
  2. {  
  3. [DisplayName("姓名")]  
  4. [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources))]  
  5. public string Name { get; set; }  
  6.  
  7. [DisplayName("性別")]  
  8. [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources))]  
  9. [Domain("M""F""m""f", ErrorMessageResourceName = "Domain", ErrorMessageResourceType = typeof(Resources))]  
  10. public string Gender { get; set; }  
  11.  
  12. [DisplayName("年齡")]  
  13. [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources))]  
  14. [Range(18, 25, ErrorMessageResourceName = "Range", ErrorMessageResourceType = typeof(Resources))]  
  15. public int? Age { get; set; }  
  16. }  

三個ValidationAttribute特性采用的錯誤消息均定義在項目默認的資源文件中(我們可以采用這樣的步驟創(chuàng)建這個資源文件:右鍵選擇Solution Exploror中的項目,并在上下文菜單中選擇“屬性”選項打開“項目屬性”對象框。最后在對話框中選擇“資源”Tab頁面,通過點擊頁面中的鏈接創(chuàng)建一個資源文件),具體定義如圖2所示。

由于ASP.NET MVC會自動提取應用在綁定參數(shù)類型上的ValidationAttribute特性對綁定的參數(shù)實施自動化驗證,所以我們根本不需要在具體的Action方法中來對參數(shù)作手工驗證。如下面的代碼片斷所示,我們在Action方法Index中不再顯式調(diào)用Validate方法,但是運行該程序并在輸入不合法數(shù)據(jù)的情況下提交表單后依然會得到如圖1所示的輸出結果。

 

 
  1. public class HomeController : Controller  
  2. {  
  3. //其他成員  
  4. [HttpPost]  
  5. public ActionResult Index(Person person)  
  6. {  
  7. if (!ModelState.IsValid)  
  8. {  
  9. return View(person);  
  10. }  
  11. else 
  12. {  
  13. return Content("輸入數(shù)據(jù)通過驗證");  
  14. }  
  15. }  
  16. }  

三、讓數(shù)據(jù)類型實現(xiàn)IValidatableObject接口

除了將驗證規(guī)則通過ValidationAttribute特性直接定義在數(shù)據(jù)類型上并讓ASP.NET MVC在進行參數(shù)綁定過程中據(jù)此來驗證參數(shù)之外,我們還可以將驗證操作直接定義在數(shù)據(jù)類型中。既然我們將驗證操作直接實現(xiàn)在了數(shù)據(jù)類型上,意味著對應的數(shù)據(jù)對象具有“自我驗證”的能力,我們姑且將這些數(shù)據(jù)類型稱為“自我驗證類型”。這些自我驗證類型是實現(xiàn)了具有如下定義的接口IValidatableObject,該接口定義在“System.ComponentModel.DataAnnotations”命名空間下。

 

 
  1. public interface IValidatableObject  
  2. {  
  3. IEnumerable<ValidationResult> Validate( ValidationContext validationContext);  
  4. }  

如上面的代碼片斷所示,IValidatableObject接口具有唯一的方法Validate,針對自身的驗證就實現(xiàn)在該方法中。對于上面演示實例中定義的數(shù)據(jù)類型Person,我們可以按照如下的形式將它定義成自我驗證類型。

 

 
  1. public class Person: IValidatableObject  
  2. {  
  3. [DisplayName("姓名")]  
  4. public string Name { get; set; }  
  5.  
  6. [DisplayName("性別")]  
  7. public string Gender { get; set; }  
  8.  
  9. [DisplayName("年齡")]  
  10. public int? Age { get; set; }  
  11.  
  12. public IEnumerable<ValidationResult> Validate( ValidationContext validationContext)  
  13. {  
  14. Person person = validationContext.ObjectInstance as Person;  
  15. if (null == person)  
  16. {  
  17. yield break;  
  18. }  
  19. if(string.IsNullOrEmpty(person.Name))  
  20. {  
  21. yield return new ValidationResult("'Name'是必需字段"new string[]{"Name"});  
  22. }  
  23.  
  24. if (string.IsNullOrEmpty(person.Gender))  
  25. {  
  26. yield return new ValidationResult("'Gender'是必需字段"new string[] { "Gender" });  
  27. }  
  28. else if (!new string[]{"M","F"}.Any( g=>string.Compare(person.Gender,g, true) == 0))  
  29. {  
  30. yield return new ValidationResult("有效'Gender'必須是'M','F'之一"new string[] { "Gender" });  
  31. }  
  32.  
  33. if (null == person.Age)  
  34. {  
  35. yield return new ValidationResult("'Age'是必需字段"new string[] { "Age" });  
  36. }  
  37. else if (person.Age > 25 || person.Age < 18)  
  38. {  
  39. yield return new ValidationResult("'Age'必須在18到25周歲之間"new string[] { "Age" });  
  40. }  
  41. }  
  42. }  

如上面的代碼片斷所示,我們讓Person類型實現(xiàn)了IValidatableObject接口。在實現(xiàn)的Validate方法中,我們從驗證上下文中獲取被驗證的Person對象,并對其屬性成員進行逐個驗證。如果數(shù)據(jù)成員沒有通過驗證,我們通過一個ValidationResult對象封裝錯誤消息和數(shù)據(jù)成員名稱(屬性名),該方法最終返回的是一個元素類型為ValidationResult的集合。在不對其他代碼作任何改動的情況下,我們直接運行該程序并在輸入不合法數(shù)據(jù)的情況下提交表單后依然會得到如圖1所示的輸出結果。

四、讓數(shù)據(jù)類型實現(xiàn)IDataErrorInfo接口

上面我們讓數(shù)據(jù)類型實現(xiàn)IValidatableObject接口并將具體的驗證邏輯定義在實現(xiàn)的Validate方法中,這樣的類型能夠被ASP.NET MVC所識別,后者會自動調(diào)用該方法對綁定的數(shù)據(jù)對象實施驗證。如果我們讓數(shù)據(jù)類型實現(xiàn)IDataErrorInfo接口也能實現(xiàn)類似的自動化驗證效果。

IDataErrorInfo接口定義在“System.ComponentModel”命名空間下,它提供了一種標準的錯誤信息定制方式。如下面的代碼片段所示,IDataErrorInfo具有兩個成員,只讀屬性Error用于獲取基于自身的錯誤消息,而只讀索引用于返回指定數(shù)據(jù)成員的錯誤消息。

 

 
  1. public interface IDataErrorInfo  
  2. {  
  3. string Error { get; }  
  4. string this[string columnName] { get; }  
  5. }  

同樣是針對上面演示的實例,現(xiàn)在我們對需要被驗證的數(shù)據(jù)類型Person進行了重新定義。如下面的代碼片斷所示,我們讓Person實現(xiàn)了IDataErrorInfo接口。在實現(xiàn)的索引中,我們將索引參數(shù)columnName視為屬性名稱,根據(jù)它按照上面的規(guī)則對相應的屬性成員實施驗證,并在驗證失敗的情況下返回相應的錯誤消息。在不對其他代碼作任何改動的情況下,我們直接運行該程序并在輸入不合法數(shù)據(jù)的情況下提交表單后依然會得到如圖1所示的輸出結果。

 

 
  1. public class Person : IDataErrorInfo  
  2. {  
  3. [DisplayName("姓名")]  
  4. public string Name { get; set; }  
  5.  
  6. [DisplayName("性別")]  
  7. public string Gender { get; set; }  
  8.  
  9. [DisplayName("年齡")]  
  10. public int? Age { get; set; }  
  11.  
  12. [ScaffoldColumn(false)]  
  13. public string Error { get; private set; }  
  14.  
  15. public string this[string columnName]  
  16. {  
  17. get 
  18. {  
  19. switch (columnName)  
  20. {  
  21. case "Name":  
  22. {  
  23. if(string.IsNullOrEmpty(this.Name))  
  24. {  
  25. return "'姓名'是必需字段";  
  26. }  
  27. return null;  
  28. }  
  29. case "Gender":  
  30. {  
  31. if (string.IsNullOrEmpty(this.Gender))  
  32. {  
  33. return "'性別'是必需字段";  
  34. }  
  35. else if (!new string[] { "M""F" }.Any(  
  36. g => string.Compare(this.Gender, g, true) == 0))  
  37. {  
  38. return "'性別'必須是'M','F'之一";  
  39. }  
  40. return null;  
  41. }  
  42. case "Age":  
  43. {  
  44. if (null == this.Age)  
  45. {  
  46. return "'年齡'是必需字段";  
  47. }  
  48. else if (this.Age > 25 || this.Age < 18)  
  49. {  
  50. return "'年齡'必須在18到25周歲之間";  
  51. }  
  52. return null;  
  53. }  
  54. defaultreturn null;  
  55.  
  56. }  
  57. }  
  58. }  
  59. }  

以上就是采用4種不同的編程模式來進行針對綁定參數(shù)驗證的實現(xiàn)代碼,希望對大家的學習有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美乱码精品一区 | xxxxhdvideosex| 久久国产精品久久久久久电车 | 欧美一级特黄特色大片免费 | 国产成年免费视频 | 国产乱淫a∨片免费观看 | 久久丝袜脚交足黄网站免费 | www.99久| 少妇的肉体的满足毛片 | 免费毛片电影 | 亚洲一区 国产精品 | 日本一级黄色大片 | 免费看性xxx高清视频自由 | 久久伊| 国产91免费看 | 美国av免费看 | 国产99久久精品 | 国产女厕一区二区三区在线视 | 热99re久久免费视精品频软件 | 精品国产欧美一区二区 | 午色影院| 国产精品爱久久久久久久 | 国产精品久久久久久久久久大牛 | 成人免费观看毛片 | 欧美日本国产精品 | 国产va在线观看免费 | www.成人精品| 免费看日韩av | 久久久久久免费 | 天天草天天干天天射 | 一区二区三区日韩 | 老司机免费福利午夜入口ae58 | 久久精品欧美视频 | 毛片大全免费 | 日韩av电影免费看 | 欧美精品一区二区三区在线 | 粉嫩粉嫩一区二区三区在线播放 | 成人免费自拍视频 | japanesexxxxxxxhd| 黄色香蕉视频 | 懂色粉嫩av久婷啪 |