ASP.NET MVC系列文章
【02】浅谈Google Chrome浏览器(操作篇)(上)
【03】浅谈Google Chrome浏览器(操作篇)(下)
【04】浅谈ASP.NET框架
【07】浅谈ASP.NET MVC 路由
【08】浅谈ASP.NET MVC 视图
【10】浅谈jqGrid 在ASP.NET MVC中增删改查
【13】浅谈NuGet在VS中的运用
【14】浅谈ASP.NET 程序发布过程
一 概述
关于数据验证和数据注解,是任何软件系统不可小觑的必要模块,在软件系统中起到举足轻重的作用。
1.从数据验证的验证方式来说,我们一般分为客户端验证和服务端验证(或者两种方式相结合);
2.从数据验证的作用角度来说,数据验证起到很重要的作用,如防止漏洞注入,防止网络攻击(XSS等),确保数据安全,确保数据合理性,防止垃圾数据等作用;
3.从数据验证的种类来书,一般分为第三方验证(如我们用Jquery写好验证插件,在客户端用AJAX验证)和基于ASP.NET MVC框架的数据验证;
4.从数据注解的作用角度来说,如界面关键字段的友好设置和提示等;
说了那么多,那么本篇文章会讲解哪些内容呢?
本篇文章主要讲解基于ASP.NET MVC框架的数据验证特性和数据注解。
二 数据验证
(一)ASP.NET MVC 内置六大类数据验证特性
1.在ASP.NET MVC中,验证特性定义在System.ComponentModel.DataAnnotations命名空间中,因此我们在使用验证特性前,需要引入命名空间:
using System.ComponentModel.DataAnnotations;
2.ASP.NET MVC内置了六大验证特性:Required,StringLength,RegularExpression,Range,Compare和Remote;
3.数据验证使用单个验证特性:指数据验证只使用其中一个验证特性
[Required]
public string Username { get; set; }
4.有些属性,单个验证特性无法满足,需要两个及其以上验证特性组合,如密码,至少要满足两个条件:
(1)必填 (2)不少于6位
[Required]
[StringLength()]
public string Password { get; set; }
5.用代码演示一下五大验证特性(Remote除外)
Models:UserInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; using System.ComponentModel.DataAnnotations; namespace DataValidate.Models
{
public class UserInfo
{
//定义用户名必填
[Required]
public string UserName { get; set; }
//定义密码必填,且满足6位
[Required]
[StringLength(,MinimumLength =)]
public string Password { get; set; }
//验证两次输入的密码是否一致
[Required]
[Compare("Password", ErrorMessage = "两次密码输入不一致")]
public string ConfirmPassword { get; set; }
//定义邮件为必填,且满足邮件格式
[Required]
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
public string Email { get; set; }
//定义年龄为必填,且1-130岁之间
[Required]
[Range(, )]
public int Age { get; set; }
}
}
Controller:DefaultController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; using DataValidate.Models;
namespace DataValidate.Controllers
{
public class DefaultController : Controller
{
// GET: Default public ActionResult Index()
{
return View();
} public ActionResult DataValidateDemo(UserInfo userInfo)
{
UserInfo _userInfo = new UserInfo();
_userInfo.UserName = userInfo.UserName;
return View("Index");
}
}
}
View:Index.cshtml
@model DataValidate.Models.UserInfo @{
ViewBag.Title = "Index";
} <h2>Index</h2> @using (Html.BeginForm("DataValidateDemo", "Default"))
{
<div>@Html.Label("用户名"): @Html.TextBoxFor(m=>m.UserName)
@Html.ValidationMessageFor(m=>m.UserName)
</div>
<div>@Html.Label("密码"):@Html.TextBox("Password")
@Html.ValidationMessageFor(m=>m.Password)</div> <div>@Html.Label("确认密码"):@Html.TextBox("ConfirmPassword")
@Html.ValidationMessageFor(m=>m.ConfirmPassword)</div>
<div>
@Html.Label("邮件"):@Html.TextBox("Email")
@Html.ValidationMessageFor(m => m.Email)
</div>
<div>
@Html.Label("年龄"):@Html.TextBox("Age")
@Html.ValidationMessageFor(m => m.Age)
</div>
<div><input type="submit" value="提交" /></div>
}
我们来看看测试结果
6.为什么要把Remote剔出来单独讲解呢?
我们知道,除Remote以外的五大验证特性,命名空间均为System.ComponentModel.DataAnnotations,而Remote特性的命名空间却是System.Web.Mvc。
Remote,从字面意思可以看出,“远程”,即远程验证。Remote特性指利用服务器端的回调函数执行客户端的验证逻辑(当执行到有Remote特性的元数据时,会自动地调用相应的控制器下的Action)。
举个例子:新会员注册时,一般手机号是不允许重复的,检查DB中是否已存在手机号,可以使用Remote特性来验证。
Model:UserInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; using System.ComponentModel.DataAnnotations; namespace DataValidate.Models
{
public class UserInfo
{
//定义用户名必填
[Required]
public string UserName { get; set; }
//定义密码必填,且满足6位
[Required]
[StringLength(,MinimumLength =)]
public string Password { get; set; }
//验证两次输入的密码是否一致
[Required]
[Compare("Password", ErrorMessage = "两次密码输入不一致")]
public string ConfirmPassword { get; set; }
//定义邮件为必填,且满足邮件格式
[Required]
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
public string Email { get; set; }
//定义年龄为必填,且1-130岁之间
[Required]
[Range(, )]
public int Age { get; set; } [Required]
[System.Web.Mvc.Remote("CheckTelephone", "Default", ErrorMessage ="手机号码已经存在")]
public string Telephone { get; set; }
}
}
DefaultController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; using DataValidate.Models;
namespace DataValidate.Controllers
{
public class DefaultController : Controller
{
// GET: Default public ActionResult Index()
{
return View();
} public ActionResult DataValidateDemo(UserInfo userInfo)
{
UserInfo _userInfo = new UserInfo();
_userInfo.UserName = userInfo.UserName;
return View("Index");
} public ActionResult CheckTelephone(string telephone)
{
if (telephone=="")
{
return Json("手机号"+telephone+ "已经存在", JsonRequestBehavior.AllowGet);
}
return Json(true, JsonRequestBehavior.AllowGet); }
}
}
Index.cshtml
@model DataValidate.Models.UserInfo @{
ViewBag.Title = "Index";
Html.EnableClientValidation();
Html.EnableUnobtrusiveJavaScript(); } <h2>Index</h2> @using (Html.BeginForm("DataValidateDemo", "Default"))
{
<div>
@Html.Label("用户名"): @Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</div>
<div>
@Html.Label("密码"):@Html.TextBox("Password")
@Html.ValidationMessageFor(m => m.Password)
</div> <div>
@Html.Label("确认密码"):@Html.TextBox("ConfirmPassword")
@Html.ValidationMessageFor(m => m.ConfirmPassword)
</div>
<div>
@Html.Label("邮件"):@Html.TextBox("Email")
@Html.ValidationMessageFor(m => m.Email)
</div>
<div>
@Html.Label("年龄"):@Html.TextBox("Age")
@Html.ValidationMessageFor(m => m.Age)
</div>
<div>
@Html.Label("手机号码"):@Html.TextBox("Telephone")
@Html.ValidationMessageFor(m => m.Telephone)
</div>
<div><input type="submit" value="提交" /></div>
}
@section scripts{ <script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
}
测试结果:
给大家留一个思考题:如何验证多个参数?
在实际项目开发中,一般我们验证的不仅仅是一个参数,而是多个参数,如用户名和手机号,身份证号等一起验证,关于多参数验证,Remote验证特性又是怎么处理的呢?
(二) 验证错误提示
1.什么是验证错误提示?
指验证字段在验证不通过时,反馈给用户的提示信息,如密码不能低于6位,手机号必须为11位,年龄限制在1-130岁之间等,通过验证特性的ErroMessage实现。
[Required]
[StringLength(,MinimumLength =,ErrorMessage ="密码不能低于6位数")]
2.错误验证提示大致分为两大类:默认错误提示和自定义错误提示。
(1)默认错误提示:当我们不指定ErroMessage的值时,ASP.NET MVC框架会指定默认值。
//定义密码必填,且满足6位
[Required]
[StringLength(,MinimumLength =)]
public string Password { get; set; }
Result:
(2)自定义值:我们为ErrorMessage指定具体自定义的值“密码不能低于6位数”
[Required]
[StringLength(,MinimumLength =,ErrorMessage ="密码不能低于6位数")]
public string Password { get; set; }
Result:
3.为什么要有自定义错误提示?
(1)为用户呈现友好提示,我们来看一下2中的默认值和自定义值;
默认值:字段Password必须是一个字符串,其最小长度为6,最大长度为128(这么一句话,要是给不懂程序的用户看了,肯定会疯掉,
很简单,对程序员来说,“字段”二字再基础不过,可对用户来说,他可能会问,字段是什么东东?)
自定义值:密码不能低于6位数(无论是程序员还是用户,都能看得明白)
(2)提高通用性,比如对美国提供英语提示,对俄罗斯提供俄语提示等;
4.如何实现通用性国际化?
在如上的自定义验证错误提示中,我们使用的是硬编码的形式,然而,面向国际市场开发的,这种硬编码错误消息提示是不实用的,因为我们要为不同地区显示
不同内容,实现国际化,庆幸的是,所有验证特性都允许为本地化的错误消息提示指定资源类型名称和资源名称,感兴趣的读者朋友,请参照How to:Set the
Cultrue and UI Cultrue for ASP.NET Page Globalization(sites:http://msdn.microsoft.com/en-us/library/bz9tc508.aspx)
思考题,如何实现错误消息通用性国际化?
(三) 验证原理
关于数据验证,我们思考这样一个问题:验证是什么时候发生的?如何才能知道验证失败?
本节我们将来回答这个问题。
1.要想充分理解验证原理,我们应该先熟悉几个基本概念:模型绑定器,模型元数据,模型验证器和模型状态(这部分内容,本篇文章不论述,大家知道这几个概念即可,具体详情内容,
将在接下来的文章中与大家分享:【ASP.NET MVC系列】浅谈ASP.NET MVC 模型)
2.默认情况下,ASP.NET MVC框架在模型绑定时就执行验证逻辑,在执行验证时,分为隐式执行和显示执行。
(1)隐式执行:一般指在控制器的Action中带有参数时,就会隐式执行模型验证。如下方法带有参数,因此就隐式执行模型绑定。
public ActionResult DataValidateDemo(UserInfo userInfo)
{
UserInfo _userInfo = new UserInfo();
_userInfo.UserName = userInfo.UserName;
return View("Index");
}
(2)显示执行:只利用控制器的UpdateModel或TryUpdateModel方式时,显示执行模型绑定。
3.模型绑定器一旦使用新值更新模型属性时,就会利用当前的模型元数据获得模型的所有验证器;
4.ASP.NET MVC运行时,DataAnnotationsModelValidator与数据验证一起工作;
5.DataAnnotationsModelValidator验证器会找到所有的验证特性并执行它所包含的验证逻辑;
6.模型绑定器捕获所有失败的验证规则,并把他们放入模型状态中;
7.模型绑定主要的副产品是模型状态,模型状态包含如下内容:
(1)包含用户放入模型属性中的所有值;
(2)包含每个属性相关联的所有错误;
(3)包含所有与模型对象本身有关的错误;
8.如果模型状态中存在错误,ModelState.IsValid就返回false;
9.控制操作和验证错误是怎样执行的?
控制器操作决定模型验证失败和验证成功时的执行流程。
(1)验证成功时:当验证成时,操作通常会执行必要的步骤来保存或更新用户信息;
(2)验证失败时:当验证失败时,操作一般会重新渲染提交模型值得视图;
(四)自定义验证
ASP.NET MVC之所以强大,在于其提供强大的自定义和扩展性,关于这个内容,会在后续的文章:“【SP.NET MVC系列】浅谈ASP.NET MVC八大类扩展”中深入讲解这两个强大的特性。
1.基于ASP.NET MVC的自定义验证,一般分为两大类型:将验证逻辑封装在自定义数据中和将验证逻辑封装在模型对象中。
(1)将验证逻辑封装在自定义数据中:复杂,但可复用性高;
(2)将验证逻辑封装在模型对象中:简单,但可复用性低;
2.将验证逻辑封装在自定数据中(会在后续的文章:“【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展”中深入讲解)
3.将验证逻辑封装模型对象中(会在后续的文章:“【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展”中深入讲解)
三 数据注解
(一)七大类型ASP.NET MVC内置数据注解
1.Dispaly特性:(1)模型属性设置友好的显示名称 (2)控制UI上属性的显示顺序;
2.ScaffoldColumn特性:隐藏HTML辅助方法;
3.DisplayFormat特性:处理属性的各种格式化选项;
4.ReadOnly特性:确保默认的模型绑定器不使用新值来更新;
5.DataType特性:提供关于属性的特定信息;
6.UIHint特性:(1)为ASP.NET MVC运行时提供模板名称,以备调用模板辅助方法渲染输出时使用 (2)自定义模板辅助方法;
7.HiddenInput特性:渲染type为hidden的元素;
四 参考文献
【01】ASP.NET MVC5 高级编程(Jon Galloway,Brad Wilson,K.Scott Allen,David Matson 著 ,孙远帅 译)
【02】ASP.NET MVC5编程实战(第3版)(Dino Esposite 著,潘丽丞 译)
五 版权区
- 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。
- 博主网址:http://www.cnblogs.com/wangjiming/。
- 极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。
- 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2098469527@qq.com。
- 可以转载该博客,但必须著名博客来源。
【ASP.NET MVC系列】数据验证和注解的更多相关文章
-
【MVC】ASP.NET MVC之数据验证
前端传到后端数据的不可信任性,DRY("Don't Repeat Yourself") 设计原则.MVC3.0出了后端数据验证特性,鼓励你只定义一次功能或行为,然后在应用程序中各处 ...
-
ASP.NET MVC 扩展数据验证 转
此文只作记录 public class MaxWordsAttribute : ValidationAttribute { public MaxWordsAttribute(int maxWords) ...
-
Asp.Net Mvc后台数据验证自测小Demo
使用过MVC的同学一定不陌生MVC的模型绑定和模型校验,使用起来非常方便,定义好Entity之后,在需要进行校验的地方可以打上相应的Attribute,在Action开始时检查ModelState的I ...
-
【ASP.NET MVC系列】浅谈数据注解和验证
[ASP.NET MVC系列]浅谈数据注解和验证 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google C ...
-
【ASP.NET MVC系列】浅谈ASP.NET MVC 视图与控制器传递数据
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
<;转>;ASP.NET学习笔记之MVC 3 数据验证 Model Validation 详解
MVC 3 数据验证 Model Validation 详解 再附加一些比较好的验证详解:(以下均为引用) 1.asp.net mvc3 的数据验证(一) - zhangkai2237 - 博客园 ...
-
ASP.NET MVC系列:从Controller访问Model数据
在项目解决方案中,添加一个MoviesController控制器,选择对应的模板,和模型类以及数据上下文:关于如何添加模型类和数据上下文,我们在ASP.NET MVC系列:添加模型中已经介绍过
-
Hibernate Validation,Spring mvc 数据验证框架注解
1.@NotNull:不能为 Null,但是可以为Empty:用在基本数据类型上. @NotNull(message="{state.notnull.valid}", groups ...
-
【ASP.NET MVC系列】浅谈NuGet在VS中的运用
一 概述 在我们讲解NuGet前,我们先来看看一个例子. 1.例子: 假设现在开发一套系统,其中前端框架我们选择Bootstrap,由于选择Bootstrap作为前端框架,因此,在项目中,我们 ...
随机推荐
-
linux 安装vbox增强工具
首先在虚拟机控制台点设备--------安装增强功能,这样会用虚拟光驱加载增强功能镜象. 然后打开终端,先转到root身份:=================su================= f ...
-
如何通过maven ,将本地jar 安装到仓库中去。
场景: 现在很多公司,都有 maven 的私服 ,在maven项目中,基本上有两个仓库 ,一个是maven的公共仓库,一个是私服仓库: 有的时候,我们download 别人的代码的时候,pom文件中报 ...
-
jQuery DataTable-JavaScript API
虽然大多数时候你的Javascript交互将通过使用datatable初始化对象作为描述在使用这个网站的部分,有时,你会发现它有用一些外部控制表.可以使用以下函数从jQuery.dataTable对象 ...
-
java的类加载机制
1.概述 Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class ...
-
IOS 获取手机各种信息
/手机序列号 NSString* identifierNumber = [[UIDevice currentDevice] uniqueIdentifier]; NSLog(@&qu ...
-
MyBatis 一级、二级缓存
一级 默认session就有一级缓存,session有C/U/D操作或者session.clearCache();session.commit();都会清空缓存: 二级在mapper.xml中添加&l ...
-
CAN总线学习记录之二:系统结构与帧结构
CAN总线系统结构 CAN 控制器 接收控制单元中微处理器发出的数据,处理数据并传给 CAN 收发器 CAN 收发器 将数据传到总线 or 从总线接收数据给 CAN 控制器 CAN 数据传递终端 避 ...
-
转:slf4j-api、slf4j-log4j12、log4j之间关系
原文:https://www.cnblogs.com/lujiango/p/8573411.html 1. slf4j-api slf4j:Simple Logging Facade for Java ...
-
linux下man手册简介
Linux提供了丰富的帮助手册,当你需要查看某个命令的参数时不必到处上网查找,只要man一下即可.Linux 的man手册共有以下几个章节: 1.Standard commands (标准命令)2.S ...
-
九度-题目1195:最长&;最短文本
http://ac.jobdu.com/problem.php?pid=1195 题目描述: 输入多行字符串,请按照原文本中的顺序输出其中最短和最长的字符串,如果最短和最长的字符串不止一个,请全部输出 ...