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

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

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

 using System;
using System.ComponentModel.DataAnnotations; namespace ModelValidation.Models {
public class Appointment { public string ClientName { get; set; } [DataType(DataType.Date)]
public DateTime Date { get; set; } public bool TermsAccepted { get; set; }
}
}

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

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

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

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

 @model ModelValidation.Models.Appointment
@{
ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4> @using (Html.BeginForm()) {
<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" />
}

最后,在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都去掉,代码最终如下:

 public class Appointment
{
public string ClientName { get; set; } public DateTime Date { get; set; } public bool TermsAccepted { get; set; }
}

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

 [HttpPost]
public ViewResult MakeBooking(Appointment appt)
{ if (string.IsNullOrEmpty(appt.ClientName))
{
ModelState.AddModelError("ClientName", "Please enter your name");
} if (ModelState.IsValidField("Date") && DateTime.Now > appt.Date)
{
ModelState.AddModelError("Date", "Please enter a date in the future");
} if (!appt.TermsAccepted)
{
ModelState.AddModelError("TermsAccepted", "You must accept the terms");
} if (ModelState.IsValid)
{
return View("Completed", appt);
}
else
{
return View();
}
}

上面可以看到我们在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视图文件,改后的内容如下:

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

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

详解ASP.NET MVC Model验证的更多相关文章

  1. 详解ASP.NET MVC 控制器

    1   概述 在阅读本篇博文时,建议结合上篇博文:详解ASP.NET MVC 路由  一起阅读,效果可能会更好些. Controller(控制器)在ASP.NET MVC中负责控制所有客户端与服务端的 ...

  2. ASP.NET MVC Model验证(五)

    ASP.NET MVC Model验证(五) 前言 上篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现, 然而在MVC框架中还给我们提供了其它 ...

  3. ASP.NET MVC Model验证(四)

    ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...

  4. ASP.NET MVC Model验证(三)

    ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...

  5. ASP.NET MVC Model验证(二)

    ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...

  6. ASP.NET MVC Model验证(一)

    ASP.NET MVC Model验证(一) 前言 前面对于Model绑定部分作了大概的介绍,从这章开始就进入Model验证部分了,这个实际上是一个系列的Model的绑定往往都是伴随着验证的.也会在后 ...

  7. 详解ASP.NET MVC的请求生命周期

    本文的目的旨在详细描述asp.net mvc请求从开始到结束的每一个过程. 我希望能理解在浏览器输入url并敲击回车来请求一个asp.net mvc网站的页面之后发生的任何事情. 为什么需要关心这些? ...

  8. 【转】【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式

    本文属转载,来源: http://www.byywee.com/page/M0/S868/868615.html 关于Model验证官方资料: http://msdn.microsoft.com/zh ...

  9. 【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式

    转自:http://www.cnblogs.com/easy5weikai/p/3843131.html 关于Model验证官方资料: http://msdn.microsoft.com/zh-cn/ ...

随机推荐

  1. 【spring】InitializingBean接口

    apollo 源码中有这么一个类 public class ReleaseMessageScanner implements InitializingBean @Override public voi ...

  2. MongDB from execCommand not master

    count failed: not master{ , "errmsg" : "not master" } at src/mongo/shell/query.j ...

  3. 17、OpenCV Python 数字验证码识别

    __author__ = "WSX" import cv2 as cv import numpy as np from PIL import Image import pytess ...

  4. Udp 网络字节序

    1.网络上的数据是一个字节一个字节的串行传递的. 2.字节序,规定,在内存里存储时,低字节在前称为小端,高字节在前称为大端,(现在主流系统都是小端的) 3.网络字节序,如果先传高字节,则是大端传输:如 ...

  5. 多线程 NSOpeartion 的使用

    NSOperation简介 相对于 GCD ,具有面向对象的特征,比 GCD 更简单易用,代码可读性强 NSOperatioin 单独使用时, 不具有开辟新线程的能力, 只是同步执行操作, 需要配合 ...

  6. Android---16进制与字节数组

    16进制字符串与字节数组进行转换 package string; import java.util.Arrays; /** * byte[]与16进制字符串相互转换 * * @date:2017年4月 ...

  7. redis原理及实现

    1 什么是redis redis是nosql(也是个巨大的map) 单线程,但是可处理1秒10w的并发(数据都在内存中) 使用java对redis进行操作类似jdbc接口标准对mysql,有各类实现他 ...

  8. origin横纵坐标颠倒

    origin默认是只能多个纵坐标,不能多个横坐标,所以这种情况只能先作成多个Y,然后像这样exchange一下.

  9. UVALive - 5963 ad-hoc

    注意到合法条件是对称的,那很有可能与2有关, 小于2表示没有这一页,大于2表示冲突了 我也不知道这样做对不对的(输入范围很迷),试一下就A了... #include<bits/stdc++.h& ...

  10. [转]【NODE】用WS模块创建加密的WS服务(WSS)

    [From] https://luojia.me/2015/07/21/%E3%80%90node%E3%80%91%E7%94%A8ws%E6%A8%A1%E5%9D%97%E5%88%9B%E5% ...