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. 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计

    类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...

  2. 864. Shortest Path to Get All Keys

    We are given a 2-dimensional grid. "." is an empty cell, "#" is a wall, "@& ...

  3. kali linux之xss

    攻击web客户端 客户端脚本语言(弹窗,广告,在浏览器中执行,javascript) javascript--与java语言无关,使用最广的客户端脚本语言 xss(cross-site scripti ...

  4. 简单的opengl步骤模板

    以下内容整理自:https://learnopengl-cn.github.io/01%20Getting%20started/03%20Hello%20Window/ 一.初始化 glfw 并设置相 ...

  5. 【bzoj2813】 奇妙的Fibonacci数列 线性筛

    Description Fibonacci数列是这样一个数列: F1 = 1, F2 = 1, F3 = 2 . . . Fi = Fi-1 + Fi-2 (当 i >= 3) pty忽然对这个 ...

  6. Java面向对象之内部类(访问格式)

    一.基础概念 1.内部类是定义在类中的类.A类需要直接访问B类中的成员时,可以将A类定义到B类中,作为B类的内部类存在. 2.内部类可以相当于外部类中的一个成员,可以被成员修饰符所修饰.(如:publ ...

  7. apache ab性能测试实践

    E:\developtools\apache ab\httpd-2.4.25-x86-vc14-r1\Apache24\bin>ab -n 15000 -c 600 "http://1 ...

  8. jquery.from帮助类

    /** * 将form里面的内容序列化成json * 相同的checkbox用分号拼接起来 * @param {obj} 需要拼接在后面的json对象 * @method serializeJson ...

  9. APUE第八章-进程控制

    一.进程标识 二.函数fork 1.写时复制,copy-on-write 2.文件共享,父进程等待子进程完成,子进程结束后,它对任一共享描述符的读写操作的文件偏移量已做相应的更新,同时操作时,可以考虑 ...

  10. sql 表字段模糊连接

    select AreauserCode,RtuName from TB_AreaUser as tau right join TB_MaintenanceInfo inf on inf.RtuName ...