返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model
返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model
作者:webabcd
介绍
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> }
OK
[源码下载]