系列目錄javascript
注:本節閱讀須要有MVC 自定義驗證的基礎,不然比較吃力html
一直以來表單的驗證都是不可或缺的,微軟的東西仍是作得比較人性化的,從webform到MVC,都作到了雙向驗證前端
單單的用js實現的前端驗證是極其不安全的,因此本次咱們來看看MVC上的自帶的註解驗證,自定義驗證java
一樣的MVC提供了一系列內置的數據驗證註解jquery
MVC3項目模板自帶的登陸模型類以下:web
public class LogOnModel { [Required] [Display(Name = "User name")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } }
MVC3自帶的模板項目中已經有了:ajax
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
而後在被驗證的View頁面上要參加如許兩個JavaScript,重視,他們是依附於JQuery的:正則表達式
<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>
驗證消息的顯示有兩種,一種是ValidationSummary,它能夠顯示一份驗證消息的彙總,包含從後臺Action裏返回的消息。數據庫
@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
另外一種是Model中各屬性對應HTML控件的驗證消息:json
@Html.ValidationMessageFor(m => m.UserName)
因此要前端代碼有驗證效果必須引入jquery庫
可是每每系統自帶的驗證是遠遠知足不了咱們的,咱們須要更加靈活的封裝,不可能我要驗證數字是否填了 0-9之間都要去寫一個表表達式吧,還好官方也靈活的提供了擴展,自定義驗證。
自定義驗證我就很少說了,在園裏搜索一下就不少原理及編寫方法。這裏我爲你們共享一個經常使用的自定驗證
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; using System.Web.Mvc; using System.Globalization; using System.Web.Security; using System.Text.RegularExpressions; namespace App.Models { /** 使用說明 * 繼承 ValidationAttribute 抽象類,重寫 IsValid() 方法,以實現服務端驗證 * 實現 IClientValidatable 接口的 GetClientValidationRules() 方法,以實現客戶端驗證 * * 1. [IntRangeExpression(18, 30)] 數字在18與30之間,能夠不填寫,但填寫就進入驗證 * 2. [MaxWordsExpression(50)] 字符數在不能大50,能夠不填寫,但填寫就進入驗證 * 3. [NotNullExpression] 驗證是否爲空且 調用 * 4. [DateExpression] 是不是日期格式:2012-10-1 * 5. [IsCharExpression] 只能是數字,字母,下劃線,中劃線組成,能夠不填寫 * 6. [ChinaCharExpression] 只能輸入漢字,能夠不填寫 * 7. [NotEqualExpression("abcd")] 不能等於指定的值,能夠不填寫:如不能等於abcd * 8. [ContainExpression("abc")] 驗證是否包含指定字符串,能夠不填寫:如必須包含abc * 9. [NotContainExpression("abc")] 驗證不能指定字符串,能夠不填寫,如不能含有abc *10. [IsIntegerEpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意整數 1,-5 *11. [IsPositiveIntegerExpression] 驗證是不是數字格式,能夠不填寫,必須是任意正整數 25 *12. [IsNegativeIntegerExpression] 驗證是不是數字格式,能夠不填寫,必須是任意負整數 -25 *13. [IsDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意浮點數 12.12,12,-12.12 *14. [IsPositiveDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意正浮點數 1.4 *15. [IsNegativeDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意負浮點數 -1.2 *16. [EmailExpression] 驗證是不是Email *17. [PhoneExpression] 驗證是不是中國電話號碼 如:0769-222222-222 正確格式爲:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。 *18. [SiteExpression] 驗證是不是一個完整的網址 如:www.163.com *19. [IsNumberExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意數字 * * * 組合使用演示 * [DisplayName("姓名")] 名稱 * [NotNullExpression] 不能爲空 * [MaxWordsExpression(50)] 最多50個字符,25個漢字 * [IsCharExpression] 只能由數字,字母,中劃線,下劃線組成(通常用於驗證ID) * [NotEqualExpression("admin")] 不能包含有admin字符串 * public string Id { get; set; } * * 數字判斷演示 * [IsNumberExpression] 能夠不填寫,填寫判斷是不是數字 * [DisplayName("代號")] * public int? age { get; set; } * 非空字斷使用 * //[Required(ErrorMessageResourceType = typeof(ErrorRs), ErrorMessageResourceName = "IsNumberExpression")] * 或//[Required(ErrorMessage="必須填寫這個字段")] 來覆蓋本地化 如public int age; int?爲可空字端 **/ /// <summary> /// [IntRangeExpression(18, 30)] 數字在18與30之間,能夠不填寫,但填寫就進入驗證 /// </summary> public class IntRangeExpressionAttribute : ValidationAttribute, IClientValidatable { long minMum { get; set; } long maxMum { get; set; } public IntRangeExpressionAttribute(long minimum, long maximum) { minMum = minimum; maxMum = maximum; } public override bool IsValid(object value) { if (value == null) return true; long intValue = Convert.ToInt64(value); return intValue >= minMum && intValue <= maxMum; } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須在{1}和{2}之間", name, minMum, maxMum); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule validationRule = new ModelClientValidationRule() { ValidationType = "isinteger", ErrorMessage = FormatErrorMessage(metadata.DisplayName) }; // 向客戶端驗證代碼傳遞參數 validationRule.ValidationParameters.Add("param1", minMum); validationRule.ValidationParameters.Add("param2", maxMum); yield return validationRule; } } /// <summary> /// [MaxWordsExpression(50)]字符數在不能大50,能夠不填寫,但填寫就進入驗證 /// </summary> public class MaxWordsExpressionAttribute : ValidationAttribute, IClientValidatable { int maxStr { get; set; } public MaxWordsExpressionAttribute(int maximum) { maxStr = maximum; } public override bool IsValid(object value) { if (value == null) return true; string valueAsString = value.ToString(); return (Encoding.Default.GetByteCount(valueAsString) <= maxStr); } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}最多{1}個漢字,{2}個字符", name, maxStr / 2, maxStr); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule validationRule = new ModelClientValidationRule() { ValidationType = "maxwords", ErrorMessage = FormatErrorMessage(metadata.DisplayName) }; validationRule.ValidationParameters.Add("param", maxStr); yield return validationRule; } } /// <summary> /// [MinWordsExpression(50)]字符數在不能少於50個字符,能夠不填寫,但填寫就進入驗證 /// </summary> public class MinWordsExpressionAttribute : ValidationAttribute, IClientValidatable { int minStr { get; set; } public MinWordsExpressionAttribute(int minimum) { minStr = minimum; } public override bool IsValid(object value) { if (value == null) return true; string valueAsString = value.ToString(); return (Encoding.Default.GetByteCount(valueAsString) >= minStr); } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}最少{1}個字符", name, minStr); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule validationRule = new ModelClientValidationRule() { ValidationType = "minwords", ErrorMessage = FormatErrorMessage(metadata.DisplayName) }; validationRule.ValidationParameters.Add("param", minStr); yield return validationRule; } } /// <summary> /// [NotNullExpression] 驗證是否爲空且不能有空格 調用 /// </summary> public class NotNullExpressionAttribute : ValidationAttribute, IClientValidatable { static string DispalyName = ""; public NotNullExpressionAttribute() : base("{0}必須填寫") { } public override string FormatErrorMessage(string name) { return String.Format(name, DispalyName); } public override bool IsValid(object value) { if (value == null) { return false; } string valueAsString = value.ToString(); bool result = !string.IsNullOrEmpty(valueAsString); return result; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { DispalyName = metadata.DisplayName; return new[]{ new ModelClientValidationRequiredRule(FormatErrorMessage("{0}必須填寫")) }; } } /// <summary> /// [DateExpression] 是不是日期格式:2012-10-1 /// </summary> public class DateExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"((^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(10|12|0?[13578])([-\/\._])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(11|0?[469])([-\/\._])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(0?2)([-\/\._])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([3579][26]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][13579][26])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][13579][26])([-\/\._])(0?2)([-\/\._])(29)$))"; public DateExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); string valueAsString = value.ToString(); string dtvalue; if (value.ToString().IndexOf(" ") > 0) { dtvalue = valueAsString.Replace("/", "-").Substring(0, valueAsString.IndexOf(" ")); } else { dtvalue = valueAsString.Replace("/", "-"); } Match mch = reg.Match(dtvalue); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是日期格式:2012-10-10", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [IsCharExpression] 只能是數字,字母,下劃線,中劃線組成,能夠不填寫 /// </summary> public class IsCharExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^[0-9A-Za-z_-]{0,}$"; public IsCharExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}由字母,數字,劃線,劃線組成", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [ChinaCharExpression] 只能輸入漢字,能夠不填寫 /// </summary> public class ChinaCharExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^[\u4e00-\u9fa5]{0,}$"; public ChinaCharExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}只能填寫漢字", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [NotEqualExpression("abcd")],不能等於指定的值,能夠不填寫:如不能等於abcd /// </summary> public class NotEqualExpressionAttribute : ValidationAttribute, IClientValidatable { string InputString { get; set; } public NotEqualExpressionAttribute(string inputString) { InputString = inputString; } public override bool IsValid(object value) { if (value == null) return true; string valueAsString = value.ToString(); return (valueAsString != InputString); } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}不能等同於{1}", name, InputString); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule validationRule = new ModelClientValidationRule() { ValidationType = "notequal", ErrorMessage = FormatErrorMessage(metadata.DisplayName) }; validationRule.ValidationParameters.Add("param", InputString); yield return validationRule; } } /// <summary> /// [ContainExpression("abc")] 驗證是否包含指定字符串,能夠不填寫:如必須包含abc /// </summary> public class ContainExpressionAttribute : ValidationAttribute, IClientValidatable { string InputString { get; set; } public ContainExpressionAttribute(string inputString) { InputString = inputString; } public override bool IsValid(object value) { if (value == null) return true; string valueAsString = value.ToString(); return (valueAsString.Contains(InputString)); } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須不能包含字符串:{1}", name, InputString); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule validationRule = new ModelClientValidationRule() { ValidationType = "contain", ErrorMessage = FormatErrorMessage(metadata.DisplayName) }; validationRule.ValidationParameters.Add("param", InputString); yield return validationRule; } } /// <summary> /// [NotContainExpression("abc")],驗證不能指定字符串,能夠不填寫,如不能含有abc /// </summary> public class NotContainExpressionAttribute : ValidationAttribute, IClientValidatable { string InputString { get; set; } public NotContainExpressionAttribute(string inputString) { InputString = inputString; } public override bool IsValid(object value) { if (value == null) return true; string valueAsString = value.ToString(); return (!valueAsString.Contains(InputString)); } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須不能包含字符串:{1}", name, InputString); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule validationRule = new ModelClientValidationRule() { ValidationType = "notcontain", ErrorMessage = FormatErrorMessage(metadata.DisplayName) }; validationRule.ValidationParameters.Add("param", InputString); yield return validationRule; } } /// <summary> /// [IsNumberExpression] 驗證是不是數字格式,能夠不填寫,必須是任意數字 /// </summary> public class IsNumberExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^[-]?\d+(\.\d+)?$"; public IsNumberExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); string input = value.ToString(); Match mch = reg.Match(input); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是一個數字", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [IsIntegerExpression] 驗證是不是數字格式,能夠不填寫,必須是任意整數 -1,1 /// </summary> public class IsIntegerExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^-?\d+$"; public IsIntegerExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是一個整數", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [IsPositiveIntegerExpression] 驗證是不是數字格式,能夠不填寫,必須是任意正整數 25 /// </summary> public class IsPositiveNumberExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^\d+$"; public IsPositiveNumberExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是一個正整數", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [IsNegativeIntegerExpression] 驗證是不是數字格式,能夠不填寫,必須是任意負整數 -25 /// </summary> public class IsNegativeNumberExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^-?\d+$"; public IsNegativeNumberExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是一個負整數", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [IsDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意浮點數 12.12,12,-12.12 /// </summary> public class IsDecimalExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^[-]?\d+(\.\d+)?$"; public IsDecimalExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是一個浮點數", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [IsPositiveDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意正浮點數 1.4 /// </summary> public class IsPositiveDecimalExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^\d+(\.\d+)?$"; public IsPositiveDecimalExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是一個浮正點數", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [IsNegativeDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意負浮點數 -1.2 /// </summary> public class IsNegativeDecimalExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^-\d+(\.\d+)?$"; public IsNegativeDecimalExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是一個浮負點數", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [EmailExpression] 驗證是不是Email /// </summary> public class EmailExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$"; public EmailExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是郵箱地址", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// [PhoneExpression] 驗證是不是中國電話號碼 如:0769-222222-222 正確格式爲:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。 /// </summary> public class PhoneExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"^((0\d{2,5}-)|\(0\d{2,5}\))?\d{7,8}(-\d{3,4})?$"; public PhoneExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}不是正確的電話號碼,如:0769-2222222", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } /// <summary> /// 驗證是不是網址 調用[SiteExpression] /// </summary> public class SiteExpressionAttribute : RegularExpressionAttribute, IClientValidatable { static string regStr = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"; public SiteExpressionAttribute() : base(regStr) { } public override bool IsValid(object value) { if (value == null) return true; Regex reg = new Regex(regStr); Match mch = reg.Match(value.ToString()); if (mch.Success) { return true; } else { return false; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "{0}必須是網址,如:http://www.google.com", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } } } /* 雙向驗證,請加入如下代碼 // [IntRangeExpression(18, 30)] 數字在18與30之間,能夠不填寫,但填寫就進入驗證 jQuery.validator.addMethod('isinteger', function (value, element, params) { if (value >= parseInt(params['param1']) && value <= parseInt(params['param2'])) return true; return false; }); jQuery.validator.unobtrusive.adapters.add('isinteger', ['param1', 'param2'], function (options) { options.rules['isinteger'] = { param1: options.params.param1, param2: options.params.param2 }; options.messages['isinteger'] = options.message; } ); // [MaxWordsExpression(50)]字符數在不能大50,能夠不填寫,但填寫就進入驗證 jQuery.validator.addMethod('checkMaxWords', function (value, element, param) { if (strLen(value) > param) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('maxwords', ['param'], function (options) { options.rules['checkMaxWords'] = { param: options.params.param }; options.messages['checkMaxWords'] = options.message; } ); // [MinWordsExpression(50)]字符數在不能shaoyu 50,能夠不填寫,但填寫就進入驗證 jQuery.validator.addMethod('checkMinWords', function (value, element, param) { if (strLen(value) < param) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('minwords', ['param'], function (options) { options.rules['checkMinWords'] = { param: options.params.param }; options.messages['checkMinWords'] = options.message; } ); // [NotEqualExpression("abcd")],不能等於指定的值,能夠不填寫:如不能等於abcd jQuery.validator.addMethod('checkNotEqual', function (value, element, param) { if (value == param) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('notequal', ['param'], function (options) { options.rules['checkNotEqual'] = { param: options.params.param }; options.messages['checkNotEqual'] = options.message; } ); // [ContainExpression("abc")] 驗證是否包含指定字符串,能夠不填寫:如必須包含abc jQuery.validator.addMethod('checkContain', function (value, element, param) { if (value.indexOf(param) == -1) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('contain', ['param'], function (options) { options.rules['checkContain'] = { param: options.params.param }; options.messages['checkContain'] = options.message; } ); // [NotContainExpression("abc")],驗證不能指定字符串,能夠不填寫,如不能含有abc var v_checknotcontainReturn = ""; jQuery.validator.addMethod('checkNotContain', function (value, element, param) { if (value.indexOf(param) != -1) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('notcontain', ['param'], function (options) { options.rules['checkNotContain'] = { param: options.params.param }; options.messages['checkNotContain'] = options.message; } ); */
雙向驗證引入JS,不然沒法啓用前端驗證
//雙向驗證,請加入如下代碼 // [IntRangeExpression(18, 30)] 數字在18與30之間,能夠不填寫,但填寫就進入驗證 jQuery.validator.addMethod('isinteger', function (value, element, params) { if (value >= parseInt(params['param1']) && value <= parseInt(params['param2'])) return true; return false; }); jQuery.validator.unobtrusive.adapters.add('isinteger', ['param1', 'param2'], function (options) { options.rules['isinteger'] = { param1: options.params.param1, param2: options.params.param2 }; options.messages['isinteger'] = options.message; } ); // [MaxWordsExpression(50)]字符數在不能大50,能夠不填寫,但填寫就進入驗證 jQuery.validator.addMethod('checkMaxWords', function (value, element, param) { if (strLen(value) > param) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('maxwords', ['param'], function (options) { options.rules['checkMaxWords'] = { param: options.params.param }; options.messages['checkMaxWords'] = options.message; } ); // [MinWordsExpression(50)]字符數在不能shaoyu 50,能夠不填寫,但填寫就進入驗證 jQuery.validator.addMethod('checkMinWords', function (value, element, param) { if (strLen(value) < param) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('minwords', ['param'], function (options) { options.rules['checkMinWords'] = { param: options.params.param }; options.messages['checkMinWords'] = options.message; } ); // [NotEqualExpression("abcd")],不能等於指定的值,能夠不填寫:如不能等於abcd jQuery.validator.addMethod('checkNotEqual', function (value, element, param) { if (value == param) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('notequal', ['param'], function (options) { options.rules['checkNotEqual'] = { param: options.params.param }; options.messages['checkNotEqual'] = options.message; } ); // [ContainExpression("abc")] 驗證是否包含指定字符串,能夠不填寫:如必須包含abc jQuery.validator.addMethod('checkContain', function (value, element, param) { if (value.indexOf(param) == -1) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('contain', ['param'], function (options) { options.rules['checkContain'] = { param: options.params.param }; options.messages['checkContain'] = options.message; } ); // [NotContainExpression("abc")],驗證不能指定字符串,能夠不填寫,如不能含有abc var v_checknotcontainReturn = ""; jQuery.validator.addMethod('checkNotContain', function (value, element, param) { if (value.indexOf(param) != -1) return false; return true; }); jQuery.validator.unobtrusive.adapters.add('notcontain', ['param'], function (options) { options.rules['checkNotContain'] = { param: options.params.param }; options.messages['checkNotContain'] = options.message; } );
一共包含了19個經常使用驗證及封裝
* 1. [IntRangeExpression(18, 30)] 數字在18與30之間,能夠不填寫,但填寫就進入驗證
* 2. [MaxWordsExpression(50)] 字符數在不能大50,能夠不填寫,但填寫就進入驗證
* 3. [NotNullExpression] 驗證是否爲空且 調用
* 4. [DateExpression] 是不是日期格式:2012-10-1
* 5. [IsCharExpression] 只能是數字,字母,下劃線,中劃線組成,能夠不填寫
* 6. [ChinaCharExpression] 只能輸入漢字,能夠不填寫
* 7. [NotEqualExpression("abcd")] 不能等於指定的值,能夠不填寫:如不能等於abcd
* 8. [ContainExpression("abc")] 驗證是否包含指定字符串,能夠不填寫:如必須包含abc
* 9. [NotContainExpression("abc")] 驗證不能指定字符串,能夠不填寫,如不能含有abc
*10. [IsIntegerEpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意整數 1,-5
*11. [IsPositiveIntegerExpression] 驗證是不是數字格式,能夠不填寫,必須是任意正整數 25
*12. [IsNegativeIntegerExpression] 驗證是不是數字格式,能夠不填寫,必須是任意負整數 -25
*13. [IsDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意浮點數 12.12,12,-12.12
*14. [IsPositiveDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意正浮點數 1.4
*15. [IsNegativeDecimalExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意負浮點數 -1.2
*16. [EmailExpression] 驗證是不是Email
*17. [PhoneExpression] 驗證是不是中國電話號碼 如:0769-222222-222 正確格式爲:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
*18. [SiteExpression] 驗證是不是一個完整的網址 如:www.163.com
*19. [IsNumberExpression] 驗證是不是數字格式 能夠不填寫,能夠爲任意數字
使用方法
* 組合使用演示
* [DisplayName("姓名")] 名稱
* [NotNullExpression] 不能爲空
* [MaxWordsExpression(50)] 最多50個字符,25個漢字
* [IsCharExpression] 只能由數字,字母,中劃線,下劃線組成(通常用於驗證ID)
* [NotEqualExpression("admin")] 不能包含有admin字符串
* public string Id { get; set; }
*
* 數字判斷演示
* [IsNumberExpression] 能夠不填寫,填寫判斷是不是數字
* [DisplayName("代號")]
* public int? age { get; set; }
* 非空字斷使用
* //[Required(ErrorMessageResourceType = typeof(ErrorRs), ErrorMessageResourceName = "IsNumberExpression")]
* 或//[Required(ErrorMessage="必須填寫這個字段")] 來覆蓋本地化 如public int age; int?爲可空字端
摘一段代碼解釋一下吧 好比這個[NotNullExpression] 方法
public class NotNullExpressionAttribute : ValidationAttribute, IClientValidatable { static string DispalyName = ""; public NotNullExpressionAttribute() : base("{0}必須填寫") { } public override string FormatErrorMessage(string name) { return String.Format(name, DispalyName); } public override bool IsValid(object value) { if (value == null) { return false; } string valueAsString = value.ToString(); bool result = !string.IsNullOrEmpty(valueAsString); return result; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { DispalyName = metadata.DisplayName; return new[]{ new ModelClientValidationRequiredRule(FormatErrorMessage("{0}必須填寫")) }; } }
校驗的方法 IsValid
客戶端的驗證規則 GetClientValidationRules
封裝的錯誤信息 : base("{0}必須填寫") 0表明的是displayName
其餘方法都是相似的作法,你們能夠根據本身的須要擴展驗證。
咱們來看看在實際項目中的應用吧!!
//------------------------------------------------------------------------------ // <auto-generated> // 此代碼由T4模板自動生成 // 生成時間 2013-03-12 16:05:27 by App // 對此文件的更改可能會致使不正確的行爲,而且若是 // 從新生成代碼,這些更改將會丟失。 // </auto-generated> //------------------------------------------------------------------------------ using System; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; namespace App.Models.Sys { [DataContract] public class SysSampleModel { [Display(Name = "ID")] public string Id { get; set; } [NotNullExpression] [Display(Name = "名稱")] public string Name { get; set; } [Display(Name = "年齡")] [Range(0,10000)] public int? Age { get; set; } [Display(Name = "生日")] public DateTime? Bir { get; set; } [MaxLength(5)] [Display(Name = "照片")] [Required] public string Photo { get; set; } [MinLength(5)] [Display(Name = "簡介")] public string Note { get; set; } [DateExpressionAttribute] [Display(Name = "建立時間")] public DateTime? CreateTime { get; set; } } }
在model中使用了[NotNullExpression] 與[DateExpressionAttribute]日期驗證
打開咱們的代碼生成器生成SysSample的Create視圖,前提你已經建立自定義驗證的類和在Create引入驗證規則。
以前有關於系列的朋友都有這個樣例。若是沒有關注的,你能夠本身建立一個普通的。
代碼生成器生成如下代碼:
@model App.Models.Sys.SysSampleModel @using App.Common; @using App.Models.Sys; @using App.Admin; @{ ViewBag.Title = "建立"; Layout = "~/Views/Shared/_Index_LayoutEdit.cshtml"; List<permModel> perm = (List<permModel>)ViewBag.Perm; if (perm == null) { perm = new List<permModel>(); } } <script type="text/javascript"> $(function () { $("#btnSave").click(function () { if ($("form").valid()) { $.ajax({ url: "@Url.Action("Create")", type: "Post", data: $("form").serialize(), dataType: "json", success: function (data) { if (data.type == 1) { window.parent.frameReturnByMes(data.message); window.parent.frameReturnByReload(true); window.parent.frameReturnByClose() } else { window.parent.frameReturnByMes(data.message); } } }); } return false; }); $("#btnReturn").click(function () { window.parent.frameReturnByClose(); }); }); </script> <div class="mvctool bgb"> @Html.ToolButton("btnSave", "icon-save", "保存", perm, "Save", true) @Html.ToolButton("btnReturn", "icon-return", "返回",false) </div> @using (Html.BeginForm()) { <table class="fromEditTable setTextWidth300"> <tbody> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.Id): </td> <td style="width:310px"> @Html.EditorFor(model => model.Id) </td> <td>@Html.ValidationMessageFor(model => model.Id)</td> </tr> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.Name): </td> <td style="width:310px"> @Html.EditorFor(model => model.Name) </td> <td>@Html.ValidationMessageFor(model => model.Name)</td> </tr> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.Age): </td> <td style="width:310px"> @Html.EditorFor(model => model.Age) </td> <td>@Html.ValidationMessageFor(model => model.Age)</td> </tr> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.Bir): </td> <td style="width:310px"> @Html.EditorFor(model => model.Bir) </td> <td>@Html.ValidationMessageFor(model => model.Bir)</td> </tr> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.Photo): </td> <td style="width:310px"> @Html.EditorFor(model => model.Photo) </td> <td>@Html.ValidationMessageFor(model => model.Photo)</td> </tr> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.Note): </td> <td style="width:310px"> @Html.EditorFor(model => model.Note) </td> <td>@Html.ValidationMessageFor(model => model.Note)</td> </tr> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.CreateTime): </td> <td style="width:310px"> @Html.EditorFor(model => model.CreateTime) </td> <td>@Html.ValidationMessageFor(model => model.CreateTime)</td> </tr> </tbody> </table> }
預覽效果
前端若是判斷和自動輸出錯誤的關鍵代碼在$("form").valid() 這裏
後臺的關鍵判斷代碼在if (model != null && ModelState.IsValid)
只有都爲true時才經過雙向驗證,有力保證系統數據庫的安全
總結:其實極其簡單的演示,咱們建立的MVC3項目中實例已經能夠看出來,然而咱們封裝的驗證有效的重用於項目之間
若是你有過硬的正則表達式基礎,你徹底能夠寫出更多符合系統的表單驗證
這裏我只是共享我寫的一個驗證類,能夠直接使用與項目中,配合生成器生成規則驗證,其餘特性還待園友自行摸索了。