1. 程式人生 > >MVC 3 資料驗證 Model Validation 詳解

MVC 3 資料驗證 Model Validation 詳解

繼續我們前面所說的知識點進行下一個知識點的分析,這一次我們來說明一下資料驗證。其實這是個很容易理解並掌握的地方,但是這會浪費大家狠多的時間,所以我來總結整理一下,節約一下大家寶貴的時間。

在MVC 3中 資料驗證,已經應用的非常普遍,我們在web form時代需要在View端通過js來驗證每個需要驗證的控制元件值,並且這種驗證的可用性很低。但是來到了MVC 新時代,我們可以通過MVC提供的資料驗證Attribute來進行我們的資料驗證。並且MVC 提供了客戶端和伺服器端 雙層的驗證,只有我們禁用了客戶端js以後,也會執行服務端驗證,所以大大提高了我們的開發進度。今天我們就一起以一個初學者的身份來進入資料驗證的殿堂。

首先,要使MVC 資料驗證在客戶端生效,我們必須匯入必要的js庫。其中我在一篇部落格中專門介紹了通過jquery.validate.js進行鏈式驗證的方式。

1  <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
2     <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
3     <script src="
@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

然後我們就需要新增對應的Model ,其實在MVC中Model層對應的不一定是實體類,還可以是領域模型。這個區別還是存在的。我們新增一個簡單的User類,

複製程式碼 複製程式碼
 1 namespace MvcApplication4.Models
 2 {
 3     public class UserInfo
 4     {
 5         //ID編號
 6         [ScaffoldColumn(false
)] 7 [Required(AllowEmptyStrings = false, ErrorMessage = "使用者ID不能為空")] 8 [Display(Name = "記錄編號", Order = 20000)] 9 public int ID { get; set; } 10 11 [Display(Order = 15000)] 12 [Required(AllowEmptyStrings = false, ErrorMessage = "使用者名稱不能為空")] 13 [StringLength(20, MinimumLength = 6, ErrorMessage = "使用者名稱不能大於{2} 且要小於{1}")] 14 [Remote("User", "Validate", HttpMethod = "post", ErrorMessage = "使用者名稱已經存在")] 15 public string UserName { get; set; } 16 17 18 [Display(Name="password")] 19 [DataType(DataType.Password)] 20 [Required(AllowEmptyStrings = false, ErrorMessage = "密碼不能為空")] 21 [StringLength(60, MinimumLength = 20, ErrorMessage = "密碼必須在{2} 和{1}之間")] 22 public string UserPassword { get; set; } 23 24 [Required(AllowEmptyStrings = false, ErrorMessage = "郵箱必填")] 25 [RegularExpression(@"[A-Za-z0-9._%+-][email protected][A-Za-z0-9]+\.[A-Za-z]{2,4}", ErrorMessage = "{0}的格式不正確")] 26 public string Email { get; set; } 27 28 [Compare("Email", ErrorMessage = "郵箱要相同")] 29 public string TEmail { get; set; } //compare 大小寫要相同 否則不會觸發 驗證 30 31 32 [Display(Name = "身份證號碼")] 33 [RegularExpression(@"\d{17}[\d|x]|\d{15}", ErrorMessage = "身份證號碼格式錯誤")] 34 public string IdentityNo { get; set; } 35 36 [Required(AllowEmptyStrings = false, ErrorMessage = "年齡必填")] 37 [Range(10, 100, ErrorMessage = "年齡不能大於{2} 不能小於{1}")] 38 public int Age { get; set; } 39 40 [ReadOnly(true)] 41 [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:c}")] 42 [Required(ErrorMessage = "金額不能為空")] 43 [Range(typeof(decimal), "20.0", "30.0", ErrorMessage = "金額在{1}和{2}之間")] 44 public decimal Money { get; set; } 45 } 46 }
複製程式碼 複製程式碼

在Model 層UserInfo類中,我們定義了一個User應該具有的屬性,以及需要為每個屬性新增的不同驗證。設定好了Model,我們就需要通過Controller來顯示對應的View層。

其實Controller不需要做任何的處理,只需要選擇一個合適的View進行頁面顯示。最重要的是在View層。

複製程式碼 複製程式碼
 1 @{
 2     Layout = null;
 3 }
 4 @model MvcApplication4.Models.UserInfo
 5 <!DOCTYPE html>
 6 <html>
 7 <head>
 8     <title>Index</title>
 9 </head>
10 <body>
11     <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
12     <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
13     <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
14     <div>
15         @using (Html.BeginForm())
16         { 
17             @Html.ValidationSummary(true)
18             <fieldset>
19                 <legend>UserInfo</legend>
20                
21 
22                 
23                 <div class="editor-label">
24                     @Html.LabelFor(t => t.UserPassword)
25                 </div>
26                 <div class="editor-field">
27                     @Html.EditorFor(model => model.UserPassword)
28                     @Html.ValidationMessageFor(model => model.UserPassword)
29                 </div>
30                 <div class="editor-label">
31                     @Html.LabelFor(t => t.IdentityNo)
32                 </div>
33                 <div class="editor-field">
34                     @Html.EditorFor(model => model.IdentityNo)
35                     @Html.ValidationMessageFor(model => model.IdentityNo)
36                 </div>
37                 <div class="editor-label">
38                     @Html.LabelFor(t => t.Email)
39                 </div>
40                 <div class="editor-field">
41                     @Html.EditorFor(model => model.Email)
42                     @Html.ValidationMessageFor(model => model.Email)
43                 </div>
44 
45                 <div class="editor-label">
46                     @Html.LabelFor(t => t.Age)
47                 </div>
48                 <div class="editor-field">
49                     @Html.EditorFor(model => model.Age)
50                     @Html.ValidationMessageFor(model => model.Age)
51                 </div>
52                 
53                 <div class="editor-label">
54                     @Html.LabelFor(t => t.Money)
55                 </div>
56                 <div class="editor-field">
57                     @Html.EditorFor(model => model.Money)
58                     @Html.ValidationMessageFor(model => model.Money)
59                 </div>
60 
61                  <div class="editor-label">
62                     @Html.LabelFor(t => t.TEmail)
63                 </div>
64                 <div class="editor-field">
65                     @Html.EditorFor(model => model.TEmail)
66                     @Html.ValidationMessageFor(model => model.TEmail)
67                 </div>
68 
69                 @Html.EditorForModel()
70 
71             </fieldset>
72             <input type="submit" value="提交" />
73         }
74     </div>
75 </body>
76 </html>
複製程式碼 複製程式碼

我在View層中定義了兩種顯示Model資料的方式,一種是通過html.EditorFor(model)來分別顯示每個不同的屬性,另外一個簡潔的方式就是通過html.EditorForModel()進行,這個方法會提供錯誤資訊顯示等。

Model 、View、Controller都設定好了,下面我們來看一下最終執行的效果。

在效果圖中,我們看到了兩個相同的部分,這是我採用兩個不同的顯示方式顯示的效果。其中有兩個Age,這兩個只要一個驗證通過,就會驗證通過。根本原因就是它們的ID值是相同的。

看到了實際效果,我們來逐個分析一下每個驗證Attribute的實現方式 極其注意方式。

Required 必填項 表示的是這個欄位值是必填的。

[Required(AllowEmptyStrings = false, ErrorMessage = "使用者名稱不能為空")]

Display  欄位顯示的名稱  表示該欄位顯示的是Name值,而不是欄位本身的名稱

 [Display(Name="password")]

StringLength 表示的是驗證字串的長度。我們可以設定最小長度和最大長度,如果不在這個範圍內,則會提示錯誤資訊

[StringLength(20, MinimumLength = 6, ErrorMessage = "使用者名稱不能大於{2} 且要小於{1}")]

其中我們看到ErrorMessage中有佔位符存在,其實這個佔位符很容易理解,就是{0}表示的是欄位本身的名稱,{1}表示它前面的第一個引數,{2}表示它前面的第二個引數。

ScaffoldColumn  表示的是是否採用MVC框架來處理 設定為true表示採用MVC框架來處理,如果設定為false,則該欄位不會在View層顯示,裡面定義的驗證也不會生效。

 [ScaffoldColumn(false)]

Remote  表示的是進行遠端驗證,這個相當於我們採用ajax方式來非同步的請求伺服器,並返回資訊。最常用的就是驗證使用者名稱是否重複。下面這個驗證是非同步呼叫ValidateController下面的User Action 並且返回結果為json值。

  [Remote("User", "Validate", HttpMethod = "post", ErrorMessage = "使用者名稱已經存在")]

DataType 表示的是欄位的資料型別 這個會影響到欄位在View層的顯示效果。如果設定為password,則輸入時會用*替換。

 [DataType(DataType.Password)]

RegularExpression 正則表示式驗證。正則表示式我曾經在我的一篇部落格中有所介紹。正則表示式是驗證字串的利器,我們必須掌握的。前面是驗證模式,後面是出錯顯示的錯誤資訊。

 [RegularExpression(@"[A-Za-z0-9._%+-][email protected][A-Za-z0-9]+\.[A-Za-z]{2,4}", ErrorMessage = "{0}的格式不正確")]

Compare  比較兩個欄位值是否相同,這個如果我們採用js進行驗證的話,最少需要三行,這還只是客戶端驗證。那麼在MVC中就比較容易實現了。

 [Compare("Email", ErrorMessage = "郵箱要相同")]

在Compare 驗證中有一個地方需要注意,就是第一個引數,它是另一個欄位的名稱,我們一定要注意大小寫正確,如果錯誤的話,驗證就不會通過的。

Range 表示的大小資料的大小驗證。這個Attribute可以驗證int,double,decimal等資料型別的值的大小範圍。 表示的是在10和100之間,包括10和100

 [Range(10, 100, ErrorMessage = "年齡不能大於{2} 不能小於{1}")]

ReadOnly 表示欄位是否只讀。 這個在View層我有時測試會沒有執行。具體原因還未知。

DisplayFormat 表示的資料顯示的樣式。其實這個不屬於資料驗證特性,而應該屬於資料格式。如果要啟用格式設定,第一個引數一定要設定為true,第二個就和我們toString()方法後面的引數一樣。

[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:c}")]

UiHint  告訴MVC 指定的模版。

HiddenInput 隱藏域顯示

其實我個人是將資料驗證的這些特性分為兩類,一類是真正的進行驗證,Required,Range,StringLength,Display,Remote,RegularExpression,Compare,Range。這些特性是真正會進行驗證的Attribute。另外幾個Display,ReadOnly,DataType,DisplayFormat,ScaffoldColumn等和欄位的顯示有關,沒有真正的和伺服器端進行驗證。

我們可以使用MVC提供的各種驗證特性,那麼我們是否可以自己來定義自定義特性驗證呢。MVC有著巨大的可擴充套件性,我們也可以自己進行擴充套件,有兩種擴充套件方式,一種就是可以重複使用的和MVC框架中驗證,只要繼承自ValidationAttribute 就可以實現重複使用的驗證特性,另一種就是內包含的模式,它是隻驗證特定的Model,繼承自IValidatableObject可以實現字包含的驗證。

可重複使用的驗證特性,繼承自ValidationAttribute。

複製程式碼 複製程式碼
 1   public class MaxWordsAttribute : ValidationAttribute
 2     {
 3 
 4         public MaxWordsAttribute(int maxWords)
 5             : base("{0} 字串過長")
 6         {
 7             _maxWords = maxWords;
 8         }
 9         private readonly int _maxWords;
10 
11         protected override ValidationResult IsValid(object value, ValidationContext validationContext)
12         {
13             if (value != null)
14             {
15                 var valueAsString = value.ToString();
16                 if (valueAsString.Split(' ').Length > _maxWords)
17                 {
18                     var errorMessage = FormatErrorMessage(
19                     validationContext.DisplayName);
20                     return new ValidationResult(errorMessage);
21                 }
22             }
23             return ValidationResult.Success;
24         }
25     }
複製程式碼 複製程式碼

MVC 驗證特性提高了我們開發的效率以及穩定性,值得我們學習。還是那句話,每天學一學,自己常進步,世界更美好。

 MVC 的驗證擴充套件特性 以及全球化,我們在以後有機會在一起學習。

相關推薦

MVC 3 資料驗證 Model Validation

繼續我們前面所說的知識點進行下一個知識點的分析,這一次我們來說明一下資料驗證。其實這是個很容易理解並掌握的地方,但是這會浪費大家狠多的時間,所以我來總結整理一下,節約一下大家寶貴的時間。 在MVC 3中 資料驗證,已經應用的非常普遍,我們在web form時代需要在View端通過js來驗證每個需要驗證的控制

MVC,MVP 和 MVVM 的

name one control ember 模式 hash 改名 主動性 主動 一、MVC MVC模式的意思是,軟件可以分成三個部分。 視圖(View):用戶界面。 控制器(Controller):業務邏輯 模型(Model):數據保存 各部分之間的通信方式如下

springMVC引入Validation

note get string getter abi res @override success temp 本文簡單介紹如何引入validation的步驟,如何通過自定義validation減少代碼量,提高生產力。特別提及:非基本類型屬性的valid,GET方法的處理,va

實戰 :Spring MVC + 註解 +SqlServer 框架搭建及

原始碼下載:http://download.csdn.NET/detail/u010469432/6786687 https://blog.csdn.net/u010469432/article/details/17587699 先說一下Spring3 MVC的優點: spring&nb

Linux下多資料夾編寫Makefile

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

jdbc:oracle:thin:@192.168.3.98:1521:orcl(

原文章:點選開啟連結 整理自網際網路 一、 jdbc:oracle:thin:@192.168.3.98:1521:orcljdbc:表示採用jdbc方式連線資料庫oracle:表示連線的是oracle資料庫thin:表示連線時採用thin模式(oracle中有兩種模式)jdbc:oralce

sk buff封裝和解封裝網路資料包的過程

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

python 基本資料型別--字串例項

  字串(str) :把字元連成串. 在python中⽤', ", ''', """引起來的內容被稱為字串 。   注意:python中沒有單一字元說法,統一稱叫字串。 一、切片和索引   1、索引:索引就是下標,從0開始      str= "我是字串" print("str[0]=",st

JAVA基本資料型別、引用資料型別-引數傳遞

1:基本型別的引數傳值 對於基本資料型別,修改這個值並不會影響作為引數傳進來的那個變數,因為你修改的是方法的區域性變數,是一個副本。實參的精度級別應等於或低於形參的精度級別,否則報錯。 class JB{ void f(int x, int y){ x=x+1;

Docker(3):Dockerfile配置

FROM  : 指定base映象 MAINTAINER :設定映象的作者,可以是任意的字串 COPY :將檔案從build context 複製到映象             COPY 支援兩種形式:CO

VC常用資料型別使用轉換

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

sk_buff封裝和解封裝網路資料包的過程

可以說sk_buff結構體是Linux網路協議棧的核心中的核心,幾乎所有的操作都是圍繞sk_buff這個結構體進行的,它的重要性和BSD的mbuf類似(看過《TCP/IP詳解 卷2》的都知道),那麼sk_buff是什麼呢?      

Tensorflow官網CIFAR-10資料分類教程程式碼

標題 概述 對CIFAR-10 資料集的分類是機器學習中一個公開的基準測試問題,本教程程式碼通過解決CIFAR-10資料分類任務,介紹了Tensorflow的一些高階用法,演示了構建大型複雜模型的一些重要技巧,著重於建立一個規範的網路組織結構,訓練並進行評估,為建立更大規模更加複雜的

kaggle 入門題 Tatanic | top_5%解法及資料分析常用技巧

Titanic: 身為女性且來自頭等艙的ROSE存活率高達95%,身為男性且來自二等艙的Jack存活率不足10%。悲劇似乎在他們上船的那一刻就已經註定了。 姓名:李子羽 學號:2015300009 日期:2018/10/07 1.任務簡介 泰坦尼克號的沉沒是歷

JDBC元資料操作-- DatabaseMetaData介面

package com.util;   import java.sql.CallableStatement;   import java.sql.Connection;   import java.sql.DatabaseMetaData;   import java.sql.DriverMana

5.3 以太坊原始碼3

一、轉賬的概念和交易的基本流程 使用者輸入轉入的地址和金額 系統用轉賬地址的私鑰對交易進行簽名(確保這筆交易是由發起交易的所有人) 對交易進行驗證 存入交易快取池 廣播交易 二、交易的資料 type

mysql資料備份匯入匯出

1、mysqldump 命令工具說明 引數註解: mysqldump 是採用SQL 級別的備份機制,它將資料表導成 SQL 指令碼檔案,在不同的 MySQL 版本之間升級時相對比較合適,這也是最

Unity3d中特殊資料夾以及作用

1.Editor Editor資料夾可以在根目錄下,也可以在子目錄裡,只要名子叫Editor就可以。比如目錄:/xxx/xxx/Editor  和 /Editor 是一樣的,無論多少個叫Editor的資料夾都可以。Editor下面放的所有資原始檔或者指令碼檔案都不會被打進發

Apache Hadoop1.1.1+Apache Oozie3.3.2搭建安裝過程(親測)

寫在前面: 最近需要定製的原因,需要將原來Cloudera版本的Hadoop更改為Apache版本的Hadoop和Oozie,對官方文件的學習,發現Hadoop1.1.1和Oozie3.3.2的組合比較好,所以,經過幾天的搭建,終於成功了,現在把心得分享出來,希望給需要的朋

[三]基礎資料型別之Integer

Integer 基本資料型別int  的包裝類 Integer 型別的物件包含一個 int 型別的欄位 屬性簡介 值為 2^31-1 的常量,它表示 int 型別能夠表示的最大值 @Native public static final int