ASP.NET MVC5+EF6+EasyUI 後臺管理系統(33)-MVC 表單驗證

系列目錄javascript

注:本節閱讀須要有MVC 自定義驗證的基礎,不然比較吃力html

一直以來表單的驗證都是不可或缺的,微軟的東西仍是作得比較人性化的,從webform到MVC,都作到了雙向驗證前端

單單的用js實現的前端驗證是極其不安全的,因此本次咱們來看看MVC上的自帶的註解驗證,自定義驗證java

一樣的MVC提供了一系列內置的數據驗證註解jquery

  1. 不爲空驗證  [Required(ErrorMessage = "不能爲空")]
  2. 長度驗證     [StringLength(10, MinimumLength = 2)]  
  3. 取值範圍     [Range(1, 3)]
  4. 類型驗證     [DataType(DataType.Date)]
  5. 正則表達     [RegularExpression(@」[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+/.[A-Za-z]{2,4}」)]   Email Demo
  6. 遠程驗證     [Remote("CheckUserNameExists", "ValidationDemo", ErrorMessage = "用戶名已存在")]
  7. 請求驗證     [AllowHtml] 容許傳入HTML
  8. 等等.....

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;
            }
         );
 */
View Code

雙向驗證引入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;
            }
         );
 
View Code

一共包含了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>
}
View Code

預覽效果

前端若是判斷和自動輸出錯誤的關鍵代碼在$("form").valid() 這裏

後臺的關鍵判斷代碼在if (model != null && ModelState.IsValid)

只有都爲true時才經過雙向驗證,有力保證系統數據庫的安全

總結:其實極其簡單的演示,咱們建立的MVC3項目中實例已經能夠看出來,然而咱們封裝的驗證有效的重用於項目之間

         若是你有過硬的正則表達式基礎,你徹底能夠寫出更多符合系統的表單驗證

         這裏我只是共享我寫的一個驗證類,能夠直接使用與項目中,配合生成器生成規則驗證,其餘特性還待園友自行摸索了。

相關文章
相關標籤/搜索