MVC验证02-自定义验证规则、邮件验证

超、凢脫俗 2021-10-15 10:34 590阅读 0赞

本文体验MVC自定义验证特性,来实现对邮件的验证。对于刚写完的自定义验证特性,起初只能支持后端验证。如果要让前端jquery支持,还必须对jquery的验证进行扩展。

本文与”MVC验证01-基础、远程验证“相关,如有需要,请参考。

当我们验证有关Email属性的时候,我们可能这样写:

  1. [RegularExpression(@"\w.+\@\w.+")]
  2. public string Email { get; set; }

这仅仅考虑了@符号,但这还不够,我们又可能这样写:

  1. [RegularExpression(@"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$")]
  2. public string Email { get; set; }

这样略显”臃肿”,实际上,我们可以扩展MVC的ValidateAttribute特性,做到“一次封装,多次使用”。

自定义验证特性

ContractedBlock.gif ExpandedBlockStart.gif

  1. 展开using System.ComponentModel.DataAnnotations;
  2. using System.Text.RegularExpressions;
  3. namespace MvcValidation.Extension
  4. {
  5. public sealed class EmailAttribute : ValidationAttribute
  6. {
  7. public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$";
  8. public EmailAttribute()
  9. {
  10. }
  11. //重写基类方法
  12. public override bool IsValid(object value)
  13. {
  14. if (value == null)
  15. return true;
  16. if (value is string)
  17. {
  18. Regex regEx = new Regex(reg);
  19. return regEx.IsMatch(value.ToString());
  20. }
  21. return false;
  22. }
  23. }
  24. }

注意:
把自定义扩展类声明为sealed class。
此处验证邮件的正则表达式不见得是最完美的。

自定义特性的用武之地:View model

ContractedBlock.gif ExpandedBlockStart.gif

  1. 展开using MvcValidation.Extension;
  2. public class RegisterModel
  3. {
  4. [Required]
  5. [StringLength(6, MinimumLength = 2)] //加
  6. [Display(Name = "用户名")]
  7. [Remote("CheckUserName","Validate", ErrorMessage = "远程验证用户名失败")]
  8. public string UserName { get; set; }
  9. [Required]
  10. [DataType(DataType.EmailAddress)]
  11. [Display(Name = "邮件")]
  12. [Email]
  13. public string Email { get; set; }
  14. [Required]
  15. [StringLength(100, ErrorMessage = "{0}栏位最少{2}个字,最多{1}个字", MinimumLength = 6)]
  16. [DataType(DataType.Password)]
  17. [Display(Name = "密码")]
  18. public string Password { get; set; }
  19. [DataType(DataType.Password)]
  20. [Display(Name = "确认密码")]
  21. [System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "密码和确认密码不匹配。")]
  22. public string ConfirmPassword { get; set; }
  23. }

Register.cshtml

ContractedBlock.gif ExpandedBlockStart.gif

  1. 展开@model MvcValidation.Models.RegisterModel
  2. @{
  3. ViewBag.Title = "注册";
  4. }
  5. <hgroup class="title">
  6. <h1>@ViewBag.Title.</h1>
  7. <h2>创建新帐户。</h2>
  8. </hgroup>
  9. @using (Html.BeginForm()) {
  10. @Html.AntiForgeryToken()
  11. @Html.ValidationSummary()
  12. <fieldset>
  13. <legend>注册表单</legend>
  14. <ol>
  15. <li>
  16. @Html.LabelFor(m => m.UserName)
  17. @Html.TextBoxFor(m => m.UserName)
  18. </li>
  19. <li>
  20. @Html.LabelFor(m => m.Email)
  21. @Html.TextBoxFor(m => m.Email)
  22. </li>
  23. <li>
  24. @Html.LabelFor(m => m.Password)
  25. @Html.PasswordFor(m => m.Password)
  26. </li>
  27. <li>
  28. @Html.LabelFor(m => m.ConfirmPassword)
  29. @Html.PasswordFor(m => m.ConfirmPassword)
  30. </li>
  31. </ol>
  32. <input type="submit" value="注册" />
  33. </fieldset>
  34. }
  35. @section Scripts {
  36. @Scripts.Render("~/bundles/jqueryval")
  37. }

效果:
邮件验证1

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

自定义特性实现IClientValidatable接口,为实现jquery验证做准备

ContractedBlock.gif ExpandedBlockStart.gif

  1. 展开using System.ComponentModel.DataAnnotations;
  2. using System.Text.RegularExpressions;
  3. using System.Web.Mvc;
  4. namespace MvcValidation.Extension
  5. {
  6. public sealed class EmailAttribute : ValidationAttribute, IClientValidatable
  7. {
  8. public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$";
  9. public EmailAttribute()
  10. {
  11. }
  12. //重写基类方法
  13. public override bool IsValid(object value)
  14. {
  15. if (value == null)
  16. return true;
  17. if (value is string)
  18. {
  19. Regex regEx = new Regex(reg);
  20. return regEx.IsMatch(value.ToString());
  21. }
  22. return false;
  23. }
  24. public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
  25. {
  26. ModelClientValidationRule rule = new ModelClientValidationRule
  27. {
  28. ValidationType = "email",
  29. ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
  30. };
  31. yield return rule;
  32. }
  33. }
  34. }

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

扩展jquery以支持自定义扩展特性EmailAttribute

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”);

为了实现jquery客户端验证,Register.cshtml中必须的js文件包括:

1、引用query-{version}.js
2、引用jquery.validate.js
3、引用jquery.validate.unobtrusive.js
4、自定义的jquery验证扩展

由于在_Layout.cshtml中有@Scripts.Render(“~/bundles/jquery”),所有Register.cshtml中不需要引用了。
Register.cshtml中包含@Scripts.Render(“~/bundles/jqueryval”),意味着包含了对2和3的引用。
Register.cshtml中还需要引入jquery针对自定义特性EmailAttribute特性的扩展方法。

完整Register.cshtml中如下:

ContractedBlock.gif ExpandedBlockStart.gif

  1. 展开@model MvcValidation.Models.RegisterModel
  2. @{
  3. ViewBag.Title = "注册";
  4. }
  5. <hgroup class="title">
  6. <h1>@ViewBag.Title.</h1>
  7. <h2>创建新帐户。</h2>
  8. </hgroup>
  9. @using (Html.BeginForm()) {
  10. @Html.AntiForgeryToken()
  11. @Html.ValidationSummary()
  12. <fieldset>
  13. <legend>注册表单</legend>
  14. <ol>
  15. <li>
  16. @Html.LabelFor(m => m.UserName)
  17. @Html.TextBoxFor(m => m.UserName)
  18. </li>
  19. <li>
  20. @Html.LabelFor(m => m.Email)
  21. @Html.TextBoxFor(m => m.Email)
  22. </li>
  23. <li>
  24. @Html.LabelFor(m => m.Password)
  25. @Html.PasswordFor(m => m.Password)
  26. </li>
  27. <li>
  28. @Html.LabelFor(m => m.ConfirmPassword)
  29. @Html.PasswordFor(m => m.ConfirmPassword)
  30. </li>
  31. </ol>
  32. <input type="submit" value="注册" />
  33. </fieldset>
  34. }
  35. @section Scripts {
  36. @Scripts.Render("~/bundles/jqueryval")
  37. <script src="~/Scripts/jQuery.validator.email.js"></script>
  38. }

效果:

实现IClientValidatable接口效果

如何确认已经启用了jquery的验证机制呢?
在没有实现IClientValidatable之前,审查Email的表单元素,如下:

没有实现IClientValidatable接口

当实现IClientValidatable之后,审查Email的表单元素,如下:

实现IClientValidatable接口

可见,实现IClientValidatable之后,多了data-val-email属性。

注意:
jQuery中本身包含了对Email的验证,这里对jquery的验证作扩展是为了演示。

转载于:https://www.cnblogs.com/darrenji/p/3579492.html

发表评论

表情:
评论列表 (有 0 条评论,590人围观)

还没有评论,来说两句吧...

相关阅读