在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
有时候我觉得,很多人将一个具体的技术细节写的那么复杂,我觉得没有必要,搞得很多人一头雾水的,你能教会别人用就成了,具体的细节可以去查MSDN什么的,套用爱因斯坦的名言:能在网上查到的就不要去记,用的时候拿过来就是。应用层面的东东,没必要深究,真正的核心已经被那些大胡子老外们搞定了,你要说你非想搞明白某个东东,那你可以把你的时间用在架构和管理上去,亦或是你也搞个编译器(搞swift语言的那家伙就是捯饬的这个)什么的,玩玩金融,甚至把把妹子都比你去研究一门最底层的技术细节强,我们常说面向抽象编程,说白了就是低层要依赖高层,所以还是研究点高端的东东对你以后有帮助! 言归正传,MVC验证走起,不过只此一篇,希望能讲多少是多少吧! 一、基于数据注解特性的验证A、你如果想用数据注解特性,那就必须要引入以下命名空间:using System.ComponentModel.DataAnnotations;可以注意到,这个命名空间不是以System.Web开头的,这也说明了它并不单单是为Web项目准备的,如何其它类型的项目都可以使用。 例如:对于一个注册用的model,在其上面用特性验证 using System.ComponentModel.DataAnnotations; 注:错误消息还可以用占位符,体会一下好处在哪 [Required(ErrorMessage=”Your {0} is required.”)] public string Name { get; set; } B、在view中用HtmlHelper的方法就可以实现客户端验证了(前提是要开启客户端验证)@Html.ValidationSummary()会输出所有验证错误, 一般放在Form头处 大概就是下面的格式: @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命名空间里边: public class Employee { public int EmpId { get; set; } [DisplayName("Employee Name")] [Remote("IsEmployeeNameAvailable", "Validation")] //使用RemoteAttribute,指定验证的Controller和Action public String EmployeeName { get; set; } } 然后你再写个Action就行了,由于比较简单这里就不再写了! 注:正则表达式特性也很有用的,例如: [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; } 注意:
所以改写一下: 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; } } } 注意:
其实还没有结束呢,还要扩展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) 最后,有一些验证还可以用JQuery实现,基本上属于js的东东,这里不再陈述~ 本人对MVC验证也只是略懂一二,所以就写这么多吧~
|
请发表评论