客户端验证逻辑会对用户向表单输入的数据给出一个即时反馈。而之所以需要服务器端验证,是因为来自网络的信息都是不能被信任的。

当在ASP.NET MVC设计模式上下文中谈论验证时,主要关注的是验证模型的值

数据注解特性定义在名称空间System.ComponentModel.DataAnnotations中,它们提供了服务器端验证的功能。当在模型的属性上使用这些属性时,框架也支持客户端验证。在名称空间DataAnnotations中,有4个特性可以用来应对一般的验证场合。

1.1 Required

因为客户的名字是必须的,所以需要在模型类的属性上添加Required特性

1 [Required]
2 public string FirstName{ get; set;}

当属性是null或空时,Required特性将会引发一个验证错误。

1.2 StringLength

校验数据的长度

1 [Required]
2 [StringLength(160)]
3 public string FirstName { get; set;}

当数据长度超过160则会提醒。MinimumLength参数是一个可选项,用于设定字符串的最小长度,如下(长度>=3且<=160)

1 [Required]
2 [StringLength(160, MinimumLength=3)]
3 public string FirstName { get; set;}

1.3 RegularExpression

用于正则表达式的验证,用于邮箱、电话等属性。

1 [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
2 public string Email {get; set;}

1.4 Range

Range 特性用来指定数值类型值的最小值和最大值。

限定年龄在35~44之间:

1 [Range(35,44)]
2 public int Age {get; set;}

限定价格在0.00~49.99之间,该重载方法可限定数据类型:

1 [Range(typeof(decimal),"0.00", 49.00)]
2 public decimal Price {get; set;}

1.5 Compare

Compare特性确保模型对象的两个属性拥有相同的值,一般用于校验客户的重复输入数据

 [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
public string Email {get; set;} [Compare("Email")]
public string EmailConfirm {get; set;}

如果两次输入的e-mail地址不一致,将会提醒。

1.6 Remote

ASP.NET MVC框架还为应用程序在名称空间System.Web.Mvc中额外添加了Remote验证特性。

Remote特性可以利用服务器端的回调函数执行客户端的验证逻辑。例如避免用户注册时在数据库中产生相同用户名的用户,可以使用Remote特性把UserName的值发送到服务器,然后在服务器端的数据库中与相应的表字段值进行比较:

1 [Remote("CheckUserName", "Account")]
2 public string UserName {get ; set;}

在特性中可以设置客户端代码要调用的控制器名称可操作名称。客户端代码会自动把用户输入的UserName属性值发送发到服务器,该特性的一个重载构造方法还允许指定要发送给服务器的其他字段:

1 public JsonResult CheckUserName (string username)
2 {
3 var result = Membership.FindUserByName(username).Count ==0 ;
4 return Json(result, JsonRequestBehavior.AllowGet);
5 }

上面的控制器操作会利用与UserName属性同名的参数进行验证,并返回一个封装在JacaScript Object Notation(JSON)对象中的布尔类型值(true或false)

2.1 自定义错误提示消息及其本地化

每个验证特性都允许传递一个带有自定义错误提示消息的参数。

1 [Required( ErrorMessage = "Your last name is required")]
2 [StringLength(160, ErrorMessage="Your last name is too long")]
3 public string LastName {get ; set ;}

自定义的错误提示消息在字符串中也有一个格式项。内置特性使用友好的属性显示名称格式化错误提示消息字符串

1  [Required( ErrorMessage = "Your {0} is required")]
2 [StringLength(160, ErrorMessage="Your last name is too long")]
3 public string LastName {get ; set ;}

如果应用程序是多语言的,硬编码的方式就不适用了。可以为验证特性都允许为本地化的错误提示消息指定资源类型和资源名称。

1 [Required(ErrorMessageResource = typeof(ErrorMessages),
2 ErrorMessageResourceName="LastNameRequired")]
3 [StringLength(160, ErrorMessageResourceType = typeof(ErrorMessage),
ErrorMessageResourceName = "LastNameTooLong")]
4 public string LastName { get; set;}

3.自定义验证逻辑

两个核心应用方法:

  • 将验证逻辑封装在自定义的数据注解中
  • 将验证逻辑封装在模型对象中

把验证逻辑封装在自定义数据注解中可以实现多个模型中重用逻辑,这需要在特性内部编写代码以应对不同类型的模型,但一旦实现,新的注解就可以在多处重用。

另一方面,如果将验证逻辑直接放入模型对象中,就意味着验证逻辑可以很容易地编码实现,因为这样只需要关心一种模型对象的验证逻辑,从而方便了对对象的状态和结构做某些假定,但这种方式不利于实现逻辑的重用。

3.1 自定义注解

所有的验证注解(如Required和Range)特性最终都派生自基类ValidationAttribute,它是个抽象类,在名称空间System.ComponentModel.DataAnnotations中定义。所以,程序的验证逻辑也必须派生自ValidationAttribute类:

1 using System.ComponentModel.DataAnnotations;
2
3 namespace MvcMusicStore.Infrastructure
4 {
5 public clsaa MaxWordsAttribute : ValidationAttribute
6 {
7 .......
8 }
9 }

为了实现验证逻辑,至少需要重写基类中提供的IsValid方法的其中一个版本。重写IsValid方法时利用的ValidationContext参数,提供了很多可在IsValid方法内部使用的信息,如模型类型、模型对象实例、用来验证属性的人性化显示名称以及其他有用的信息。

此处验证单词输入数量,并设置默认错误提示信息:

 1  using System.ComponentModel.DataAnnotations;
2
3 namespace MvcMusicStore.Infrastructure
4 {
5 public clsaa MaxWordsAttribute : ValidationAttribute
6 {
7 public MaxWordsAttribute(int maxWords) : base("{0} has too many words.")
8 {
9 _maxWords = maxWords;
10 }
11
12 protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
13 {
14 var valueAsString = value.ToString();
15 if( valueAsString.Split(' ').Length > _maxWords)
16 {
17 var errorMessage = FormatErrorMessage(validationContext.DisplayName);
18 return new ValidationResult(errorMessage);
19 }
20 return ValidationResult.Success;
21 }
22 private readonly int _maxWords;
23 }
24 }

FormatErrorMessage可以使用合适的错误提示消息字符串(即使这个字符串是存储在一个本地资源文件中)。这条代码语句需要传递name属性的值,这个值可以通过validationContext参数的DisplayName属性获得。构造完验证逻辑后,就可以将其应用到任何模型属性上:

1 [Required]
2 [StringLength(160)]
3 [MaxWords(10)]
4 public string LastName {get ; set ;}

甚至可以赋予特性自定义的错误提示消息:

1  [Required]
2 [StringLength(160)]
3 [MaxWords(10, ErrorMessage = "There are too many words in {0}")]
4 public string LastName {get ; set ;}

IValidatableObject

自验证(self-validating)模型是指一个知道如何验证自身的模型对象。一个模型对象可以通过实现IValidatableObject接口来实现对自身的验证。下面在Order模型中直接实现对LastName字段中单次个数的检查:

 1 public class Order : IValidatableObject
2 {
3 public IEnumerable<ValidationResult> Validate(ValidationContext ValidationContext)
4 {
5 if(LastName != null && LastName.Split(' ').Length > 10)
6 {
7 yield return new ValidationResult("The last name has too many words!",
new []{"LastName"});
8 }
9 //....
10 }
11 }

这种方式与特性版本有几个明显的不同点:

  • MVC运行时为执行验证而调用的方法名称是Validate而不是IsValid,但更重要的是,它们返回类型和参数不同
  • Validate的返回类型是IEnumerable<ValidationResult>,而不是单独的ValidationResult对象。因为从表面上看,内部的验证逻辑验证的是整个模型,因此可能返回多个验证错误。
  • 这里没有value参数传递给Validate方法,因为在此Validate是一个模型实例方法,在其内部可以直接访问当前模型对象的属性值。

4.显示和编辑注解

4.1 Display

Display特性可为模型属性设置友好的“显示名称”

1  [Required]
2 [StringLength(160)]
3 [Display(Name="Last Name", Order=15001)]
4 public string FirstName { get; set;}

4.2 ScaffoldColumn

ScaffoldColumn特性可以隐藏HTML辅助方法(如EditorForModel和DisplayForModel)渲染的一些属性:

1 [ScaffoldColumn(false)]
2 public string Username {get; set;}

添加了这个特性之后,EditorForModel辅助方法将不再为Username字段显示输入元素和Label标签。然而需要注意的是,如果模型绑定器在请求中看到匹配的值,那么他仍然会试图为Username属性赋值。

4.3 DisplayFormat

通过命名参数,DisplayFormat特性可用来处理属性的各种格式化选项。当属性包含空值时,可以提供可选的显示文本,也可以为包含标记的属性关闭HTML编码,还可以为运行时指定一个应用于属性值的格式化字符串。

下面的代码可将模型的Total属性值格式化为货币值形式:

1 [DisplayFormat ( ApplyFormatInEditMode = true, DataFormatString "{0:c}")]
2 public decimal Total {get; set;}

4.4 ReadOnly

如果需要确保默认的模型绑定器不使用请求中的新值来更新属性,可在属性上添加ReadOnly特性:

1 [ReadOnly(true)]
2 public decimal Total {get; set;}

4.5 DataType

DataType特性可为运行时提供关于属性的特定用途信息。例如,String类型的属性可应用与e-mail地址、URL或是密码。DataType特性可满足所有这些需求:

1 [Required]
2 [DataType(DataType.Password)]
3 [Display(name="Password")]
4 public string Password {get; set;}

其他的数据类型还有Currency、Date、Time和MultilineText。

mvc中常见的属性验证的更多相关文章

  1. mvc中使用remote属性来做ajax验证

    mvc中使用remote属性来做ajax验证比較easy : [Remote("Action", "Controller", AdditionalFields ...

  2. MVC中获取模型属性的Range和StringLength验证特性设置

    MVC中的客户端及服务端模型验证信息都以ModelMetadata类型作为承载,在获得属性的ModelMetadata之后(还不知道怎么获取ModelMetadata的童鞋请自行恶补),我们可以轻松得 ...

  3. 关于MVC中模型model的验证问题

    今天在做项目练习的时候发现,MVC中使用自带的模型验证时会提前显示在界面上,比如下面所示: 这是什么原因了,是因为我在表示get请求的action里面返回了其界面所显示使用的model,我们知道mvc ...

  4. 在ASP.NET MVC中对手机号码的验证

    在ASP.NET MVC中,可以使用RegularExpression特性来验证手机号码. public class Customer { [Required(ErrorMessage = " ...

  5. css中常见的属性-----在路上(14)

    一.css文字属性 color : #999999; /*文字颜色*/ font-family : 宋体,sans-serif; /*文字字体*/ font-size : 9pt; /*文字大小*/ ...

  6. Asp .Net MVC中常用过滤属性类

    /// <summary> /// /// </summary> public class AjaxOnlyAttribute : ActionFilterAttribute ...

  7. asp.net mvc中的用户登录验证过滤器

    在WEB项目中建立 类:      public class LoginFilter : ActionFilterAttribute     {         public override voi ...

  8. python 中常见绘图属性

    fig = plt.figure(facecolor='w')#生成图 ax = fig.add_subplot(111, projection='3d')#绘制子图 ax.scatter(t[0], ...

  9. MVC中输入的保护验证用:HttpServerUtility.HtmlEncode

    安全说明: 上面的代码使用HttpServerUtility.HtmlEncode来保护应用程序的恶意输入 (即 JavaScript).详细信息请参阅如何: 在 Web 应用程序,通过应用 HTML ...

随机推荐

  1. Linux C 数据结构 ->单向链表

    之前看到一篇单向链表的博文,代码也看着很舒服,于是乎记录下来,留给自己~,循序渐进,慢慢 延伸到真正的内核链表~(敢问路在何方?路在脚下~) 1. 简介 链表是Linux 内核中最简单,最普通的数据结 ...

  2. 深入理解 Linux的进程,线程,PID,LWP,TID,TGID

    转载:https://www.linuxidc.com/Linux/2019-03/157819.htm 在Linux的top和ps命令中,默认看到最多的是pid (process ID),也许你也能 ...

  3. Python ImportError: No module named '_tkinter', please install the python3-tk package

    ImportError: No module named '_tkinter', please install the python3-tk package 这个问题的原因是使用的python3环境内 ...

  4. hdu 5101 Select (二分+单调)

    题意: 多多有一个智商值K. 有n个班级,第i个班级有mi个人.智商分别是v1,v2,.....vm. 多多要从这些人中选出两人.要求两人智商和大于K,并且两人不同班.问总共有多少种方案. 数据范围: ...

  5. 使用psftp向服务器上传文件

    老师刚才说想用psftp上传文件到服务器,我之前没听过,学了一下,总结下.我们用PSFTP主要也就是上传和下载. PSFTP是PuTTY SFTP客户端,用于本地与服务器间安全传输文件(使用SSH连接 ...

  6. jmeter 插件安装之阶梯式压测(五)

    一.Jmeter插件安装 jmeter-plugins-manager-1.4.jar 下载地址:https://jmeter-plugins.org/install/Install/ 下载之后将插件 ...

  7. PTA 哈利·波特的考试 (25分)

    PTA 哈利·波特的考试 (25分) 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变 ...

  8. freeswitch APR库

    概述 freeswitch依赖库源代码基本都可以在libs目录下找到. 在freeswitch的官方手册中,可以找到freeswitch的依赖库表格,其中freeswitch的core核心代码依赖库主 ...

  9. SpringCloud升级之路2020.0.x版-34.验证重试配置正确性(1)

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 在前面一节,我们利用 resilience4j 粘合了 OpenFeign 实现了断路器. ...

  10. 日记啦QWWQ

    随便写写 时间 :2021年11月15日 今天是在博客园创建博客的第一天,彻底放弃在CSDN中的博客,广告实在是太多了,QWQ. 来计科的第一个学期就快要结束了,期间有很多的遗憾,往后加油吧! 没什么 ...