介绍
asp.net mvc 之 asp.net mvc 3.0 新特性之 Model:
- 通过 Data Annotations 与 jQuery 的结合实现服务端和客户端的双重验证
- 双重验证中,使客户端实现远程的异步验证
- 自定义 Data Annotations 与 jQuery,以实现自定义的双重验证
示例
1、Model 中通过 Data Annotations 与 jQuery 的结合实现服务端和客户端的双重验证
Web.config
< configuration > |
<!-- |
要实现服务端和客户端的双重验证,需要做如下配置,因为双重验证中的客户端验证需要依赖此配置 |
--> |
< appSettings > |
< add key = "ClientValidationEnabled" value = "true" /> |
< add key = "UnobtrusiveJavaScriptEnabled" value = "true" /> |
</ appSettings > |
</ configuration > |
User.cs
/* |
* 在 asp.net mvc 3.0 中支持通过 Data Annotations 来实现服务端和客户端的双重验证,需要 jQuery 的支持 |
* 所有 Data Annotations 相关的 Attribute 直接用类视图看 System.ComponentModel.DataAnnotations 就行了,详细说明以前写过好多遍了,这里就不重复了 |
* 另外 System.Web.Mvc 下有一些新增的 Data Annotations |
*/ |
|
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Web; |
|
using System.ComponentModel; |
using System.ComponentModel.DataAnnotations; |
using System.Web.Mvc; |
|
namespace MVC30.Models |
{ |
public class User |
{ |
public int ID { get ; set ; } |
|
[DisplayName( "名字" )] |
[Required(ErrorMessage = "名字不能为空" )] |
public string Name { get ; set ; } |
|
[DisplayName( "密码" )] |
[Required(ErrorMessage = "密码不能为空" )] |
public string Password { get ; set ; } |
|
[DisplayName( "确认密码" )] |
[Required(ErrorMessage = "确认密码不能为空" )] |
[Compare( "Password" , ErrorMessage= "两次密码输入不一致" )] |
public string ConfirmPassword { get ; set ; } |
|
public DateTime DateOfBirth { get ; set ; } |
|
// 请求时,允许此字段包含 HTML 标记 |
[AllowHtml] |
public string Comment { get ; set ; } |
} |
} |
ValidationDemoController.cs
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Web; |
using System.Web.Mvc; |
|
using MVC30.Models; |
|
namespace MVC30.Controllers |
{ |
public class ValidationDemoController : Controller |
{ |
// 用于演示通过 Data Annotations 实现服务端和客户端的双重验证 |
public ActionResult Validation_DataAnnotations() |
{ |
var user = new User { ID = 1, Name = "webabcd" , DateOfBirth = new DateTime(1980, 2, 14), Comment = "<b>mvp</b>" }; |
|
return View( new User()); |
} |
|
[HttpPost] |
public ActionResult Validation_DataAnnotations(User user) |
{ |
return View(user); |
} |
} |
} |
Validation_DataAnnotations.cshtml
@model MVC30.Models.User |
|
@{ |
ViewBag.Title = "Validation_DataAnnotations"; |
} |
|
< h2 >ClientValidation</ h2 > |
|
<!-- |
通过 jQuery 实现客户端验证的逻辑,需要引用此 js |
--> |
< script src = "@Url.Content(" ~/Scripts/jquery.validate.min.js")" type = "text/javascript" ></ script > |
<!-- |
服务端验证与客户端验证的一一对应需要引用此 js |
--> |
< script src = "@Url.Content(" ~/Scripts/jquery.validate.unobtrusive.min.js")" type = "text/javascript" ></ script > |
|
@* |
在 MVC3 中实现客户端验证,不需要添加以下代码 |
@{ Html.EnableClientValidation(); } |
*@ |
|
@using (Html.BeginForm()) |
{ |
< fieldset > |
< legend >User</ legend > |
< div class = "editor-label" > |
@Html.LabelFor(model => model.Name) |
(测试方法:空着文本框,然后提交) |
</ div > |
< div class = "editor-field" > |
@Html.EditorFor(model => model.Name) |
@Html.ValidationMessageFor(model => model.Name) |
</ div > |
< p > |
< input type = "submit" value = "Create" /> |
</ p > |
</ fieldset > |
} |
2、Model 中通过 Data Annotations 与 jQuery 的结合实现服务端和客户端的双重验证,其中客户端可以实现远程的异步验证
User.cs
/* |
* System.Web.Mvc.Remote(string action, string controller) - 让客户端可以通过 ajax 的方式远程验证 |
* action - 实现验证逻辑的 action,即处理客户端的异步请求的 action |
* controller - 实现验证逻辑的 controller,即处理客户端的异步请求的 controller |
*/ |
|
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Web; |
|
using System.ComponentModel; |
using System.ComponentModel.DataAnnotations; |
using System.Web.Mvc; |
|
namespace MVC30.Models |
{ |
public class User |
{ |
public int ID { get ; set ; } |
|
[DisplayName( "名字" )] |
[Required(ErrorMessage = "名字不能为空" )] |
[Remote( "CheckUserNameExists" , "ValidationDemo" , ErrorMessage = "名字已存在" )] |
public string Name { get ; set ; } |
|
[DisplayName( "密码" )] |
[Required(ErrorMessage = "密码不能为空" )] |
public string Password { get ; set ; } |
|
[DisplayName( "确认密码" )] |
[Required(ErrorMessage = "确认密码不能为空" )] |
[Compare( "Password" , ErrorMessage= "两次密码输入不一致" )] |
public string ConfirmPassword { get ; set ; } |
|
public DateTime DateOfBirth { get ; set ; } |
|
// 请求时,允许此字段包含 HTML 标记 |
[AllowHtml] |
public string Comment { get ; set ; } |
} |
} |
ValidationDemoController.cs
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Web; |
using System.Web.Mvc; |
|
using MVC30.Models; |
|
namespace MVC30.Controllers |
{ |
public class ValidationDemoController : Controller |
{ |
// 用于演示客户端的远程 ajax 异步验证 |
public ActionResult Validation_Remote() |
{ |
var user = new User { ID = 1, Name = "webabcd" , DateOfBirth = new DateTime(1980, 2, 14), Comment = "<b>mvp</b>" }; |
|
return View( new User()); |
} |
|
[HttpPost] |
public ActionResult Validation_Remote(User user) |
{ |
return View(user); |
} |
|
// 用于处理客户端的异步请求,测试时请使用字符串“webabcd” |
[HttpGet] |
public ActionResult CheckUserNameExists( string name) |
{ |
return Json(name != "webabcd" , JsonRequestBehavior.AllowGet); |
} |
} |
} |
Validation_Remote.cshtml
@model MVC30.Models.User |
|
@{ |
ViewBag.Title = "Validation_Remote"; |
} |
|
< h2 >ClientValidation</ h2 > |
|
< script src = "@Url.Content(" ~/Scripts/jquery.validate.min.js")" type = "text/javascript" ></ script > |
< script src = "@Url.Content(" ~/Scripts/jquery.validate.unobtrusive.min.js")" type = "text/javascript" ></ script > |
|
@using (Html.BeginForm()) |
{ |
< fieldset > |
< legend >User</ legend > |
< div class = "editor-label" > |
@Html.LabelFor(model => model.Name) |
(测试方法:在文本框中输入“webabcd”) |
</ div > |
< div class = "editor-field" > |
@Html.EditorFor(model => model.Name) |
@Html.ValidationMessageFor(model => model.Name) |
</ div > |
< p > |
< input type = "submit" value = "Create" /> |
</ p > |
</ fieldset > |
} |
3、Model 中使用更多的 Data Annotations 以及实现自定义的 Data Annotations 和自定义 jQuery 的相关逻辑
User.cs
/* |
* 如何使用更多的 Data Annotation |
* 1、在“Tools”中选择“Extension Manager”(安装 NuGet 后会有此选项) |
* 2、搜索“DataAnnotationsExtensions”,然后安装“DataAnnotationsExtensions.MVC3”项目 |
* 3、之后就可以使用此项目所支持的多个新的 Data Annotation |
* 如何自定义 Data Annotation |
* 详见:IntegerAttribute.cs |
*/ |
|
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Web; |
|
using System.ComponentModel; |
using System.ComponentModel.DataAnnotations; |
using System.Web.Mvc; |
|
namespace MVC30.Models |
{ |
public class User |
{ |
public int ID { get ; set ; } |
|
[DisplayName( "名字" )] |
[Required(ErrorMessage = "名字不能为空" )] |
[Remote( "CheckUserNameExists" , "ValidationDemo" , ErrorMessage = "名字已存在" )] |
public string Name { get ; set ; } |
|
[DisplayName( "密码" )] |
[Required(ErrorMessage = "密码不能为空" )] |
[Integer(ErrorMessage = "密码必须是整型" )] |
public string Password { get ; set ; } |
|
[DisplayName( "确认密码" )] |
[Required(ErrorMessage = "确认密码不能为空" )] |
[Compare( "Password" , ErrorMessage= "两次密码输入不一致" )] |
public string ConfirmPassword { get ; set ; } |
|
public DateTime DateOfBirth { get ; set ; } |
|
// 请求时,允许此字段包含 HTML 标记 |
[AllowHtml] |
public string Comment { get ; set ; } |
} |
} |
IntegerAttribute.cs
/* |
* 自定义 Data Annotation,以实现与 jQuery 结合的客户端和服务端双重验证 |
*/ |
|
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Web; |
|
using System.ComponentModel.DataAnnotations; |
using System.Text.RegularExpressions; |
using System.Web.Mvc; |
|
namespace MVC30.Models |
{ |
// 继承 ValidationAttribute 抽象类,重写 IsValid() 方法,以实现服务端验证 |
// 实现 IClientValidatable 接口的 GetClientValidationRules() 方法,以实现客户端验证 |
public class IntegerAttribute : ValidationAttribute, IClientValidatable |
{ |
// 服务端验证逻辑,判断输入是否为整型 |
public override bool IsValid( object value) |
{ |
var number = Convert.ToString(value); |
return Regex.IsMatch(number, @"^[0-9]+$" ); |
} |
|
// 客户端验证逻辑,需要结合客户端验证代码,详见 Validation_Custom.cshtml 文件 |
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) |
{ |
var rule = new ModelClientValidationRule |
{ |
ErrorMessage = this .ErrorMessage, |
|
// ValidationType - 指定一个 key(字符串),该 key 用于关联服务端验证逻辑与客户端验证逻辑。注:这个 key 必须都是由小写字母组成 |
ValidationType = "isinteger" |
}; |
|
// 向客户端验证代码传递参数 |
rule.ValidationParameters.Add( "param1" , "value1" ); |
rule.ValidationParameters.Add( "param2" , "value2" ); |
|
yield return rule; |
} |
} |
} |
ValidationDemoController.cs
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Web; |
using System.Web.Mvc; |
|
using MVC30.Models; |
|
namespace MVC30.Controllers |
{ |
public class ValidationDemoController : Controller |
{ |
// 用于演示如何使用更多的 Data Annotations 来实现服务端和客户端的双重验证,以及如何自定义 Data Annotations 来实现服务端和客户端的双重验证 |
public ActionResult Validation_Custom() |
{ |
var user = new User { ID = 1, Name = "webabcd" , DateOfBirth = new DateTime(1980, 2, 14), Comment = "<b>mvp</b>" }; |
|
return View( new User()); |
} |
|
[HttpPost] |
public ActionResult Validation_Custom(User user) |
{ |
return View(user); |
} |
} |
} |
Validation_Custom.cshtml
@model MVC30.Models.User |
|
@{ |
ViewBag.Title = "ClientValidation"; |
} |
|
< h2 >ClientValidation</ h2 > |
|
< script src = "@Url.Content(" ~/Scripts/jquery.validate.min.js")" type = "text/javascript" ></ script > |
< script src = "@Url.Content(" ~/Scripts/jquery.validate.unobtrusive.min.js")" type = "text/javascript" ></ script > |
|
< script type = "text/javascript" > |
|
// 客户端验证逻辑,判断输入是否为整型 |
jQuery.validator.addMethod( |
'checkInteger', |
function (value, element) { |
var reg = new RegExp("^[0-9]+$"); |
return (reg.test(value)); |
} |
); |
|
// 将客户端验证逻辑通过 ValidationType 与服务端的相关验证逻辑结合起来 |
jQuery.validator.unobtrusive.adapters.add( |
'isinteger', // ValidationType,必须全为小写 |
['param1', 'param2'], // 接收 ModelClientValidationRule 中的参数信息 |
function (options) { |
options.rules['checkInteger'] = true; // 启用名为 checkInteger 的客户端验证逻辑 |
options.messages['checkInteger'] = options.message; // 发生验证错误后的显示信息 |
var param1 = options.params.param1; // ModelClientValidationRule 中的参数信息 |
var param2 = options.params.param2; // ModelClientValidationRule 中的参数信息 |
alert(param1 + " " + param2); |
} |
); |
|
</ script > |
|
@using (Html.BeginForm()) |
{ |
< fieldset > |
< legend >User</ legend > |
< div class = "editor-label" > |
@Html.LabelFor(model => model.Name) |
</ div > |
< div class = "editor-field" > |
@Html.EditorFor(model => model.Name) |
@Html.ValidationMessageFor(model => model.Name) |
</ div > |
< div class = "editor-label" > |
@Html.LabelFor(model => model.Password) |
(测试方法:在文本框中输入非整型的字符串) |
</ div > |
< div class = "editor-field" > |
@Html.EditorFor(model => model.Password) |
@Html.ValidationMessageFor(model => model.Password) |
</ div > |
< p > |
< input type = "submit" value = "Create" /> |
</ p > |
</ fieldset > |
} |