MVC之验证

有时候我觉得,很多人将一个具体的技术细节写的那么复杂,我觉得没有必要,搞得很多人一头雾水的,你能教会别人用就成了,具体的细节可以去查MSDN什么的,套用爱因斯坦的名言:能在网上查到的就不要去记,用的时候拿过来就是。应用层面的东东,没必要深究,真正的核心已经被那些大胡子老外们搞定了,你要说你非想搞明白某个东东,那你可以把你的时间用在架构和管理上去,亦或是你也搞个编译器(搞swift语言的那家伙就是捯饬的这个)什么的,玩玩金融,甚至把把妹子都比你去研究一门最底层的技术细节强,我们常说面向抽象编程,说白了就是低层要依赖高层,所以还是研究点高端的东东对你以后有帮助!

言归正传,MVC验证走起,不过只此一篇,希望能讲多少是多少吧!

一、基于数据注解特性的验证

SO EASY:

A、你如果想用数据注解特性,那就必须要引入以下命名空间:using System.ComponentModel.DataAnnotations;

可以注意到,这个命名空间不是以System.Web开头的,这也说明了它并不单单是为Web项目准备的,如何其它类型的项目都可以使用。

例如:对于一个注册用的model,在其上面用特性验证

using System.ComponentModel.DataAnnotations;
namespace Ctrip.Models
{
public class Register
{
[Required(ErrorMessage="用户名必须填写")]
[MinLength(6,ErrorMessage="用户名长度过短")]
public String UserName { get; set; }
[DataType(DataType.Password)]
public String Password { get; set; }
[DataType(DataType.Password)]
[Compare("Password",ErrorMessage="密码要一致")]
public String RptPassword { get; set; }
public String Email { get; set; }
public DateTime BirthDate { get; set; }
}
}

注:错误消息还可以用占位符,体会一下好处在哪

[Required(ErrorMessage=”Your {0} is required.”)]

public string Name { get; set; }

B、在view中用HtmlHelper的方法就可以实现客户端验证了(前提是要开启客户端验证)

@Html.ValidationSummary()会输出所有验证错误, 一般放在Form头处
@Html.ValidationMessageFor()是针对单个输入的验证

大概就是下面的格式:

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary() <fieldset>
<legend>Registration Form</legend>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.EditorFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.EditorFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</li>
<li>
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email)
</li>
<li>
@Html.LabelFor(m => m.BirthDate)
@Html.EditorFor(m => m.BirthDate)
@Html.ValidationMessageFor(m => m.BirthDate)
</li>
</ol>
<input type="submit" value="Register" />
</fieldset>
}

这个时候如果你不处理后端,只要客户端允许JS运行,就可以在客户端验证,而且是AJAX验证哦,不解释~

备注:客户端验证在哪里开启与关闭呢?在web.config里边,true or false,你说了算!

<appSettings>
<add key="ClientValidationEnabled" value="false" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

C、搞定后端验证

有些人说在控制器里边写一个专门的Valid()方法验证,我说这不是作死的节奏啊,有肉还吃豆腐?呵呵,说的就是下面这个东东ModelState.IsValid

[HttpPost]
public ActionResult Create(Register register)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index", "Home");
}
return View(register);
}

D、验证特性特别多,想要看的自己上网查,或者反编译上面的那个命名空间就可以看到!不过有两个特性比较特殊,是在System.Web.Mvc命名空间里边:
     RemoteAttribute和CompareAttribute,CompareAttribute的用法上面的A中已有,下面举个RemoteAttribute的例子,就是我们在网站注册的时候,要求用户名不能重复,可以用这个RemoteAttribute实现,是异步的~

public class Employee
{
public int EmpId { get; set; }
[DisplayName("Employee Name")]
[Remote("IsEmployeeNameAvailable", "Validation")] //使用RemoteAttribute,指定验证的Controller和Action
public String EmployeeName { get; set; } }

然后你再写个Action就行了,由于比较简单这里就不再写了!
警告:这个RemoteAttribute是只进行客户端验证的,服务器端不验证的,所以如果某个用户屏蔽了客户端js那就没用了

注:正则表达式特性也很有用的,例如:

[RegularExpression(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}”,ErrorMessage=”Email doesn’t look like a valid email address.”)]

具体的正则表达式你可以上网搜~

二、自定义数据注解特性验证

先说说什么是双重验证?

其实就是客户端验证加服务器端验证而已~

为什么要双重验证?

首先,客户端验证能够直接响应客户,减少了服务器压力的同时还提高了用户体验,但是你永远不能信任来自客户端的信息(用户可以关闭浏览器的脚本功能,让你的js验证彻底不起作用),所以服务器端验证也是必须的~

常规验证可以通过上面列出的这些系统预定义ValidationAttribute特性来完成,但是在很多情况下我们需要通过创建自定义的ValidationAttribute特性来解决一些特殊的验证,而且这些自定义的特性在很多地方可以重用的!

你需要做的就是重写ValidationAttribute里边的方法IsValid()而已

举个栗子:

using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions; namespace MvcValidation.Extension
{
public class EmailAttribute : ValidationAttribute
{
public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$"; public EmailAttribute()
{
} //重写基类方法
public override bool IsValid(object value)
{
if (value == null)
return true; if (value is string)
{
Regex regEx = new Regex(reg);
return regEx.IsMatch(value.ToString());
}
return false;
}
}
}

用的话,就是下面的样子:

[Email]
public string Email { get; set; }

注意:
此时的自定义的验证特性只支持后端验证,如果想支持前端jquery验证,还需要实现 IClientValidatable接口

所以改写一下:

using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using System.Web.Mvc; namespace MvcValidation.Extension
{
public sealed class EmailAttribute : ValidationAttribute, IClientValidatable
{
public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$"; public EmailAttribute()
{
} //重写基类方法
public override bool IsValid(object value)
{
if (value == null)
return true; if (value is string)
{
Regex regEx = new Regex(reg);
return regEx.IsMatch(value.ToString());
}
return false;
} public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule
{
ValidationType = "email",
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
};
yield return rule;
}
}
}

注意:
ValidationType属性的值一定要小写,否则报错。

其实还没有结束呢,还要扩展JQuery函数(jQuery.validator.email.js文件)

//扩展方法
$.validator.addMethod("email", function (value, element) {
if (value == false) {
return true;
}
this.optional(element) || /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$/i.test(value);
}); //扩展方法注册
$.validator.unobtrusive.adapters.addBool("email");

其实实现IClientValidatable之后,就是为前端的Email输入input标签添加了一个data-val-email属性而已,属性中的“email”就是ValidationType = "email"中的名字。

三、带自我验证的模型

适用场景:不需要重用验证逻辑,只是针对某一个特定的模型进行验证。

这些带自我验证的模型实现了接口IValidatableObject,该接口定义在“System.ComponentModel.DataAnnotations”命名空间下。

public interface IValidatableObject
{
IEnumerable<ValidationResult> Validate( ValidationContext validationContext);
}

举个栗子:

public class Person: IValidatableObject
{
[DisplayName("姓名")]
public string Name { get; set; }
[DisplayName("性别")]
public string Gender { get; set; }
[DisplayName("年龄")]
public int? Age { get; set; }
public IEnumerable<ValidationResult> Validate( ValidationContext validationContext)
{
Person person = validationContext.ObjectInstance as Person;
if (null == person)
{
yield break;
}
if(string.IsNullOrEmpty(person.Name))
{
yield return new ValidationResult("'Name'是必需字段", new string[]{"Name"});
}
if (string.IsNullOrEmpty(person.Gender))
{
yield return new ValidationResult("'Gender'是必需字段", new string[] { "Gender" });
}
else if (!new string[]{"M","F"}.Any( g=>string.Compare(person.Gender,g, true) == 0))
{
yield return new ValidationResult("有效'Gender'必须是'M','F'之一", new string[] { "Gender" });
}
if (null == person.Age)
{
yield return new ValidationResult("'Age'是必需字段", new string[] { "Age" });
}
else if (person.Age > 25 || person.Age < 18)
{
yield return new ValidationResult("'Age'必须在18到25周岁之间", new string[] { "Age" });
}
}
}

四、自定义验证的错误消息

通过在自定义验证特性中重写FormatErrorMessage方法来实现:

using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using System.Web.Mvc; namespace MvcValidation.Extension
{
public sealed class EmailAttribute : ValidationAttribute, IClientValidatable
{
public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$"; public EmailAttribute()
{
} //重写基类方法
public override bool IsValid(object value)
{
if (value == null)
return true; if (value is string)
{
Regex regEx = new Regex(reg);
return regEx.IsMatch(value.ToString());
}
return false;
} public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule
{
ValidationType = "email",
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
};
yield return rule;
}
/// <summary>
/// 格式化错误信息
/// </summary>
/// <param name="name">属性名</param>
/// <returns></returns>
public override string FormatErrorMessage(string name)
{ return this.ErrorMessage ?? string.Format("{0}属性没有输入正确的Email", name);
}
}
}

最后,有一些验证还可以用JQuery实现,基本上属于js的东东,这里不再陈述~

本人对MVC验证也只是略懂一二,所以就写这么多吧~

MVC之验证的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. MVC 数据验证

    MVC 数据验证 前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解.System.ComponentModel.DataAnnotations 一.基础特性 一.Required 必填 ...

  7. ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

    在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...

  8. 【MVC】ASP.NET MVC Forms验证机制

    http://www.cnblogs.com/bomo/p/3309766.html 随笔 - 121  文章 - 0  评论 - 92 [MVC]ASP.NET MVC Forms验证机制 ASP. ...

  9. MVC数据验证原理及自定义ModelValidatorProvider实现无编译修改验证规则和错误信息

    Asp.net MVC中的提供非常简单易用的数据验证解决方案. 通过System.ComponentModel.DataAnnotations提供的很多的验证规则(Required, StringLe ...

  10. MVC 数据验证[转]

    前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解. 一.基础特性 一.Required 必填选项,当提交的表单缺少该值就引发验证错误. 二.StringLength 指定允许的长度 指 ...

随机推荐

  1. php形式的内容被处理

    /** * 过滤HTML内容RETURN * * @param $string * @param bool $html * * @return array|string */ public stati ...

  2. JAVA连接ACCESS、MYSQL、SQLSEVER、ORACLE数据库

    . 概要 1.1 JDBC概念 JDBC(Java Database Connectivity)是Java语言为了支持SQL功能而提供的与数据库连接的用户的接口.JDBC中包含了一组由(Java)语言 ...

  3. Js 正则表达式 写了一个正整数或小数点或分数前两个正则表达式

    写了一个正整数或小数点或分数前两个正则表达式 /^[0-9]+([.]{1}[0-9]{1,2})? $/ 版权声明:本文博客原创文章.博客,未经同意,不得转载.

  4. CodeForces 28D Don&#39;t fear, DravDe is kind dp

    主题链接:点击打开链接 为了让球队后,删除是合法的.也就是说,对于每一个车辆, l+r+c 一样,按l+r+c分类. 然后dp一下. #include <cstdio> #include ...

  5. oracle_windows下命令启动oracle监听和服务

    1.检查监听器状态 C:\Users\Administrator>lsnrctl status 2.启动监听程序 C:\Users\Administrator>lsnrctl start ...

  6. EF中的贪婪加载和延迟加载(懒加载)

    在上一章中,我们使用了Linq对Entity Framework进行了一个查询,但是通过学习我们却发现了懒加载给我来的性能上的开销是很到的,尤其是在循环中,如果数据量不是很多的情况下还可以接受,如果数 ...

  7. Fun<>,匿名方法,Lambda表达式 冒泡排序C#

    大头文 分享,进步 冒泡排序C#实现,使用委托,包括三种方式:Fun<>,匿名方法,Lambda表达式 冒泡排序是一种简单的排序方法,适合于小量数字排序,对于大量数字(超过10个),还有更 ...

  8. .net mvc4 从客户端中检测到有潜在危险的 Request.Form 值

    [ValidateInput(false)] 即可, 网上说什么Web.Config 里面改,一点用都没有 [HttpPost] [ActionName("Edit")] [Val ...

  9. hdoj 4324 Triangle LOVE 【拓扑】

    Triangle LOVE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  10. ApacheBench(ab)使用简介

    网站性能压力测试是服务器网站性能调优过程中必不可缺少的一环.只有让服务器处在高压情况下,才能真正体现出软件.硬件等各种设置不当所暴露出的问题. 性能测试工具目前最常见的有以下几种:ab.http_lo ...