在Asp.net MVC 中,View中我们仍然需要对提交的表单进行验证。通常验证分为客户端验证,服务端验证。
客户端验证,我们可以使用JQuery validation plugin,服务端验证,除了使用ModelState属性显示错误信息到
View,还可以使用Fluent Validation for .NET,一个小巧的.net验证框架,使用fluent的接口和lambda表达式对
你的业务对象构建验证规则。而且也有对应的MVC扩展。
我们首先增加一个验证UserEntity的验证类:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using DemoMVCForm.Models; using FluentValidation; using FluentValidation.Validators; namespace DemoMVCForm { /// <summary> /// UserValidation /// </summary> /// <remark>Author : PetterLiu 2009-02-1515:54 http://wintersun.cnblogs.com </remark> public class UserValidation : AbstractValidator<UserEntity> { /// <summary> /// Initializes a new instance of the <see cref="UserValidation"/> class. /// </summary> /// <remark>Author : PetterLiu 2009-02-1515:54 http://wintersun.cnblogs.com </remark> public UserValidation() { RuleFor(u => u.UserName).NotEmpty(); RuleFor(u => u.UserName).Length(5, 16); RuleFor(u => u.Password).NotEmpty().WithMessage("必须输入密码"); RuleFor(u => u.Email).NotEmpty(); RuleFor(u => u.Email).EmailAddress(); RuleFor(u => u.Url).Url(); RuleFor(u => u.PassportID).NotEmpty(); } } /// <summary> /// UrlValidationRule<T> /// </summary> /// <typeparam name="T">T</typeparam> /// <remark>Author : PetterLiu 2009-02-1515:54 http://wintersun.cnblogs.com </remark> public class UrlValidationRule<T> : RegularExpressionValidator<T> { /// <summary> /// Initializes a new instance of the <see cref="UrlValidationRule<T>"/> class. /// </summary> /// <remark>Author : PetterLiu 2009-02-1515:54 http://wintersun.cnblogs.com </remark> public UrlValidationRule() : base(@"^http\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?$") { } } /// <summary> /// UrlValidationExtension /// </summary> /// <remark>Author : PetterLiu 2009-02-1515:54 http://wintersun.cnblogs.com </remark> public static class UrlValidationExtension { public static IRuleBuilderOptions<T, string> Url<T>(this IRuleBuilder<T, string> ruleBuilder) { return ruleBuilder.SetValidator(new UrlValidationRule<T>()); } } }
看上增加了服务端验证规则多么简单的代码,比较直观。后又增加一个验证URL的规则,用于验证输入的URL。
接着来看,如何使用它:
/// <summary> /// Registers the specified user. /// </summary> /// <param name="user">The user.</param> /// <returns></returns> /// <remark>Author : PetterLiu 2009-02-1515:56 http://wintersun.cnblogs.com </remark> public JsonResult Register(UserEntity user) { UserValidation userValidation = new UserValidation(); ValidationResult validationResult = userValidation.Validate(user); //add error state information to ModelState. validationResult.AddToModelState(ModelState, "user"); bool validationSucceeded = validationResult.IsValid; IList<ValidationFailure> failures = validationResult.Errors; //return result for json format. return Json(failures); }
通过扩展的AddToModelState方法,能让验证的错误信息返回VIEW,但实际上如果没有使用Html.ValidationMessage,
也不需要这个方法了。看实际情况选择了。最后把验证后的结果对象:ValidationFarilure通过Json格式返回。
好,来看VIEW:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Demo</title> <style type="text/css"> #inputArea { font-family: Arial, Sans-Serif; } #inputArea input, #inputArea textarea { font-family: Arial, Sans-Serif; margin-bottom: 5px; padding: 1px; border: solid 1px #85b1de; } </style> <link href="http://www.cnblogs.com/Content/Site.css" rel="stylesheet" type="text/css" /> <script src="http://www.cnblogs.com/Scripts/jquery-1.3.1.js" type="text/javascript"></script> <script src="http://www.cnblogs.com/Scripts/jquery.validate.js" type="text/javascript"></script> <script src="http://www.cnblogs.com/Scripts/jquery.form.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function() { function ProcessJson(data) { var ret = "服务器返回验证结果:\n" for (key in data) { ret += data[key].ErrorMessage; ret += "\n"; } alert(ret); } jQuery.validator.addMethod("usernamecheck", function(value, element) { return this.optional(element) || /^[a-zA-Z][a-zA-Z0-9_]{4,15}$/.test(value); }, "5-16位字母开头,允许字母数字下划线") jQuery.validator.addMethod("ppIdcheck", function(value, element) { return this.optional(element) || /^[1-9]([0-9]{14}|[0-9]{17})$/.test(value); }, "请输入正确的身份证号码(15-18位)") $("#form-sign-up").validate({ rules: { password: {required: true,usernamecheck: ""}, confirm_password: {required: true,minlength: 8,equalTo: "#password"}, username: { required: true, remote: '<%=Url.Action("IsLoginAvailable", "FormDemo") %>' }, passportId: { required: true, ppIdcheck: "" } }, messages: { confirm_password: { required: "请填写一个密码", minLength: "长度必须8个字符", equalTo: "请输入与上面相同的密码" }, username: { required: "请输入用户名", remote: jQuery.format("{0} 已经有人用了") }, checkbox11: { required: "请打勾" } }, // set this class to error-labels to indicate valid fields success: function(label) { // set as text for IE label.html(" ").addClass("checked"); }, submitHandler: function(form) { var formoption = { dataType: "json", url: '<%=Url.Action("Register", "FormDemo")%>', type: "post", success: ProcessJson // post-submit callback }; $(form).ajaxSubmit(formoption); } }); }); </script> </head> <body> <form method="post" id="form-sign-up"> <h1> Demo表单</h1> <table id="inputArea"> <tr> <td> 用户名 (试试输入 Petter): </td> <td> <input type="text" name="username" id="username" /> </td> </tr> <tr> <td> Email: </td> <td> <input type="text" name="email" id="email" class="required email" /> </td> </tr> <tr> <td> Url: </td> <td> <input type="text" name="url" id="url" class="required url" /> </td> </tr> <tr> <td> 密码: </td> <td> <input type="password" name="password" id="password" /> </td> </tr> <tr> <td> 确认密码: </td> <td> <input type="password" name="confirm_password" id="confirm_password" /> </td> </tr> <tr> <td> 记住密码 </td> <td> <input type="checkbox" name="checkbox11" id="checkbox" class="required" /> </td> </tr> <tr> <td> <label for="passportId"> 身份证号</label> <em>*</em> </td> <td> <input type="text" name="passportId" id="passportId" class="required" /> </td> </tr> <tr> <td colspan="2" align="center"> <br /> <input type="submit" id="btn1" value="提交" /> </td> </tr> </table> </form> </body> </html>
View中使用是Jquery Validation,同样是增加rule,用于客户端验证。具体可参考官方文档(后续有时间会放出中文版文档),以及之前这篇文章
《JQuery+Asp.net MVC实现用户名重名查询》
小结:在WEB页面中,是一个数据进入的接口,对数据合法性,正确性非常重要。做好表单数据验证工作可以防止那些攻击数据,以及不合理数据。
通过使用客户端和服务端双重验证,可以保证表单数据安全性。有的时候客户端验证并不是太安全的,可以设法绕开验证提交表单。所以服务端验证
也是需要的。但为了减轻服务器压力,尽量使用客户端验证。以上只是一个小小例子,欢迎讨论。希望本文对您有帮助。
作者:Petter Liu http://wintersun.cnblogs.com