详解ASP.NET MVC Model验证

ASP.NET mvc的最好的优点之一就是支持Model验证,这个特性很方便你可以选择在定义Model的时候在字段中采用特性进行注解约定,也可以在代码中自己进行手动验证。下面就来细说一下ASP.NET MVC Model验证多种方式的实现。

一、了解什么是ASP.NET MVC Model验证

首先,我们定义一个要用到的一个Model类,Appointment.cs:

 1 using System; 
 2 using System.ComponentModel.DataAnnotations; 
 3  
 4 namespace ModelValidation.Models { 
 5     public class Appointment { 
 6  
 7         public string ClientName { get; set; } 
 8  
 9         [DataType(DataType.Date)] 
10         public DateTime Date { get; set; } 
11  
12         public bool TermsAccepted { get; set; } 
13     } 
14 } 

上面Appointment的字段Date类型定义为日期类型,并用了System.ComponentModel.DataAnnotations命名空间来注解Model的字段为日期类型,如果传入不合法的日期Model就会验证不合法。

再在Site.css中加入下面的样式用来标注错误的输入项:

1 .input-validation-error { 
2     border: 1px solid #f00; 
3     background-color: #fee; 
4 }

然后,创建一个视图,MakeBooking.cshtml用来录入信息:

 1 @model ModelValidation.Models.Appointment 
 2 @{ 
 3     ViewBag.Title = "Make A Booking"; 
 4 } 
 5 <h4>Book an Appointment</h4> 
 6  
 7 @using (Html.BeginForm()) { 
 8     <p>Your name: @Html.EditorFor(m => m.ClientName)</p> 
 9     <p>Appointment Date: @Html.EditorFor(m => m.Date)</p> 
10     <p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>     
11     <input type="submit" value="Make Booking" /> 
12 }

最后,在HomeController中加入下面两个Action:

public ViewResult MakeBooking()
{
    return View();
}
[HttpPost]
public ViewResult MakeBooking(Appointment appt)
{
    if (ModelState.IsValid)
    {
        return View("Completed", appt);
    }
    else
    {
        return View();
    }
}

我们查看/Home/MakeBooking会有下图要效果:

这时我们看到Appointment Date输入框为红色的,表示输入不合法。看看这个input要样式class为:”input-validation-error text-box single-line“,而刚开始的时候为:”text-box single-line“正好多了一个”input-validation-error“,这也是刚开始我们为什么要定义一个类名为”input-validation-error“的样式的原因。换句话说,默认情况下当MVC的Model字段验证不通过的时候就会在输入的页面输入项加上一个css类”input-validation-error“。

二、采用System.ComponentModel.DataAnnotations注解Model的字段

上面我们演示了一个采用[DataType(DataType.Date)]来约定字段必须为Date类型,DataType为枚举类型,你可以选择其中的任意类型来约定你的Model字段。如下图:

其实System.ComponentModel.DataAnnotations还为我们提供了其它很多验证规则。比较常用的有:

[Required]:必填字段

[RegularExpression("xx"):正则表达式

这些都是System.ComponentModel.DataAnnotations命名空间下定义好的类,下面例举出用于Model验证的常用的类:

  • CompareAttribute             提供比较两个属性的属性。 
  • CreditCardAttribute         指定数据字段值是信用卡号码。 
  • CustomValidationAttribute     指定自定义的验证方法来验证属性或类的实例。 
  • DataTypeAttribute             指定要与数据字段关联的附加类型的名称。 
  • DisplayAttribute             提供一个通用特性,使您可以为实体分部类的类型和成员指定可本地化的字符串。 
  • EmailAddressAttribute         确认一电子邮件地址。 
  • MaxLengthAttribute             指定属性中允许的数组或字符串数据的最大长度。 
  • MinLengthAttribute             指定属性中允许的数组或字符串数据的最小长度。 
  • PhoneAttribute                 使用电话号码的正则表达式,指定数据字段值是一个格式正确的电话号码。 
  • RangeAttribute                 指定数据字段值的数值范围约束。 
  • RegularExpressionAttribute     指定 ASP.NET 动态数据中的数据字段值必须与指定的正则表达式匹配。 
  • RequiredAttribute             指定需要数据字段值。 
  • UrlAttribute                 提供 URL 验证。

三、显式手动验证一个MVC的Model

除了上面结合Model定义时System.ComponentModel.DataAnnotations下的类来约定Model验证规则这外,我们还可以在程序中手动验证显式手动验证一个MVC的Model是否合法。下面我们把Appointment之前加的DataAnnotations都去掉,代码最终如下:

1 public class Appointment
2 {
3     public string ClientName { get; set; }
4  
5     public DateTime Date { get; set; }
6  
7     public bool TermsAccepted { get; set; }
8 } 

这时,我们把接受输入的Action MakeBooking改成手动判断Model的字段是否合法:

 1 [HttpPost]
 2 public ViewResult MakeBooking(Appointment appt)
 3 {
 4  
 5     if (string.IsNullOrEmpty(appt.ClientName))
 6     {
 7         ModelState.AddModelError("ClientName", "Please enter your name");
 8     }
 9  
10     if (ModelState.IsValidField("Date") && DateTime.Now > appt.Date)
11     {
12         ModelState.AddModelError("Date", "Please enter a date in the future");
13     }
14  
15     if (!appt.TermsAccepted)
16     {
17         ModelState.AddModelError("TermsAccepted", "You must accept the terms");
18     }
19  
20     if (ModelState.IsValid)
21     {
22         return View("Completed", appt);
23     }
24     else
25     {
26         return View();
27     }
28 }

上面可以看到我们在Action方法的内部依次手动进行验证相应的每个字段的值是否满足要求,如果验证不通过就调用ModelState.AddModelError加入Model验证错误信息,这个AddModelError有两个参数,第一个为被验证的字段,第二个为要显示错误信息提示的文本。验证完了每个字段之后调用ModelState.IsValid来总的判断Model的验证之后的结果是否合法。只要有一个字段验证没通过或者我们调用了ModelState.AddModelError,ModelState.IsValid都会返回false。

 

四、在页面显示MVC的Model验证错误信息

4.1、采用汇总的形式显示MVC的Model验证错误信息

我们在上面的例子中,当验证不通过的时候我们除了把输入框变红之外,是没有显示文本提示的。其实要在页面显示MVC的Model验证错误信息也很简单,只需要在视图中调用:@Html.ValidationSummary() 就可以了。

@model MVCModelBindingDemo.Models.Appointment
@{
    ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4>
 
@using (Html.BeginForm())
{
    @Html.ValidationSummary()
    <p>Your name: @Html.EditorFor(m => m.ClientName)</p>
    <p>Appointment Date: @Html.EditorFor(m => m.Date)</p>
    <p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>
    <input type="submit" value="Make Booking" />
} 

同样我们在/Home/MakeBooking页面中什么都不录入,直接提交将会出现下图中的结果:

我们查看@Html.ValidationSummary()生成的html源码如下图:

生成的验证错误信息用一个样式名为"validation-summary-errors"的div,错误项是用ul 和li 列出。

下面来介绍一下ValidationSummary()方法的几种参数重载版本:

  • Html.ValidationSummary():生成输出所有验证错误信息。
  • Html.ValidationSummary(bool):如果bool为true,只显示model-level错误信息,也就是通过ModelState.AddModelError来注册的验证信息。如果bool为false,生成输出所有验证错误信息。
  • Html.ValidationSummary(string) :在生成输出所有验证错误信息之前显示一段文字
    Html.ValidationSummary(bool, string):在生成输出验证错误信息之前显示一段文字,同样bool为true,只显示model-level错误信息。

 

4.2、分每个属性(Property-Level )显示验证信息

除了采用上面汇总的形式显示MVC的Model验证错误信息,我们还可以分每个属性(Property-Level )显示验证信息。Property-Level验证信息是我们通过ModelState.AddModelError来注册的验证信息。下面我们改一下/Home/MakeBooking视图文件,改后的内容如下:

 1 @model MVCModelBindingDemo.Models.Appointment
 2 @{
 3     ViewBag.Title = "Make A Booking";
 4 }
 5 <h4>Book an Appointment</h4>
 6  
 7 @using (Html.BeginForm())
 8 {
 9     <p>@Html.ValidationMessageFor(m => m.ClientName)</p> 
10     <p>Your name: @Html.EditorFor(m => m.ClientName)</p> 
11     <p>@Html.ValidationMessageFor(m => m.Date)</p> 
12     <p>Appointment Date: @Html.EditorFor(m => m.Date)</p> 
13     <p>@Html.ValidationMessageFor(m => m.TermsAccepted)</p> 
14     <p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>     
15     <input type="submit" value="Make Booking" /> 
16 }

可以看到我们把@Html.ValidationSummary()去掉了,然后在每个字段后面加入了@Html.ValidationMessageFor对应字段的验证信息。验证效果如下图:

 

 

posted @ 2017-05-18 10:36  赤脚的孤儿  阅读(850)  评论(2编辑  收藏  举报