[ASP.Net MVC] 自訂Custom Validation Attribute進行Model驗證

自訂CustomValidation Attribute進行Model驗證

前言

 

在ASP.Net MVC驗證機制中,可依據Model屬性所加註的Data Annotation作為驗證條件(ex. Required, StringLenght),並讓Client/Server端都可以套用相同的驗證條件;因此當我們有特殊驗證需求時,亦可自行擴充ValidationAttribute來達到伺服端共享驗證邏輯的好處,以下將就一個簡單的例子進行說明。

 

 

實作說明

 

需求很簡單,就是一個用戶註冊介面,而用戶需要年滿20歲才可加入,因此須取得用戶的生日來推算年齡。

 

image

 

 

首先,建立繼承自ValidationAttribute的QualifiedAgeAttribute類別,再依據各別驗證邏輯來覆寫IsValid方法;在此範例中,會在建構子中傳入符合資格年齡條件,再依照生日推算年齡是否大於符合資格年齡,最後回傳驗證結果/錯誤訊息即可。詳細內容請參考以下程式碼。

 

{
    public class QualifiedAgeAttribute : ValidationAttribute
    {
        // Fields
        private int _qualifiedAge;

        // Constructors
        public QualifiedAgeAttribute(int qualifiedAge)
        {
            this._qualifiedAge = qualifiedAge;
        }

        // Methods
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            DateTime birthday = (DateTime)value;
            int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year - 1;

            if (age >= _qualifiedAge)
            {
                // valid
                return ValidationResult.Success;
            }
            else
            {
                // invalid
                var errorMsg = string.Format("Your age({0}) should be over {1}", age, _qualifiedAge);
                return new ValidationResult(errorMsg);
            }
        }
    }
}

 

接著定義會員基本資料Model,其中使用先前建立的QualifiedAgeAttribute來驗證生日(年齡)

{
    public class Member
    {
        // 必填資訊
        [Required]
        public string Name { get; set; }

        // 需超過20歲才可註冊
        [QualifiedAge(20)] 
        public DateTime Birthday { get; set; }
    }
}

 

建立Controller

{
    public class HomeController : Controller
    {
        public ActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Register(Member member)
        {
            if (ModelState.IsValid)
            {
                // do register job here...
            }
            return View();
        }

    }
}

 

建立Register Action對應的View (Register.cshtml)


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Member</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Birthday, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Birthday, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Birthday, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

 

執行後來驗證一下結果。按下Create後,驗證失敗錯誤訊息如預期般顯示。

 

image

 

 

參考資訊

 

http://www.c-sharpcorner.com/Blogs/15842/how-to-add-custom-validators-in-Asp-Net-mvc4.aspx


希望此篇文章可以幫助到需要的人

若內容有誤或有其他建議請不吝留言給筆者喔 !