選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
5 分鐘閱讀時間 (968 個字)

簡介 .NET 的 Server 端資料驗證機制: DataAnnotation Validation

mockuuups-man-working-on-macbook-air-mockup
就一個應用系統而言, 對資料格式或資料正確性的驗證是保障系統能正常運作的重要基本動作.  目前大部份應用系統都是 Web-Based, 因此在使用者輸入資料的驗證部分, 可以選擇在 Client 端 (即 Browser 或 App) 做驗證, 也可以在 Server 端做驗證, 或是兩者都做.  在 Client 端的資料驗證, 一般比較常見.  在 Visual Studio (VS) 的開發環境中, 提供有資料驗證的控制項, 可以直接拉到頁面上來驗證使用者輸入的資料.  在 Client 端的資料驗證, 基本上都是透過 JavaScript 程式來進行, 這種方式雖然可以比較不影響 Server的效能, 但是主要缺點是瀏覽器上面的 JavaScript 有可能會被關掉, 導致沒辦法做資料的驗證.

在 Server 端的資料驗證, 其實有比較簡易的方式, 即是透過 Data Annotation 的方式來對資料做驗證.  在 ASP.NET MVC 2.0 以後, 增加了 Model Validation,  可以使用 Data Annotation 的方式來執行防呆或資料驗證.  要使用 DataAnnotation Validation, 必須加入 System.ComponentModel.DataAnnotations 的 Name Space (命名空間), 然後在變數名稱(或屬性)前加上所要驗證的 Annotation 即可. 下面是一個簡單的例子.
   using System;
    using System.ComponentModel.DataAnnotations;
    using System.Collections.Generic;
    public partial class Room
    {
        [Required]
        public string RoomID { get; set; }
        [Required]
        [StringLength(6)]
        public string Roomtype { get; set; }
        public int Rate { get; set; }
    }
在 Room 這個 Class中, Roomtype 這個變數前面有兩個 Annotations, [Required] 和 [StringLength(6)].  [Required] 表示這是一個必要欄位, [StringLength(N)] 則限制最大長度, 這個長度是傳入的參數 N.  因此 Roomtype 這個欄位如果沒填或是填入的 String長度大於 6, 則會顯示如下的錯誤:



在 .NET 的 DataAnnotation 中, 提供了包括 Required, StringLength, Range, MinimumLength, MaximumLength, RegularExpression 及其他多種 Validation 的Annotation.  使用 RegularExpression 的 Annotation, 就可以驗證一些比較特殊的資料型態, 例如下面的程式片段就是利用這個方式來驗證身分證字號的格式是否正確.
[Required]
[RegularExpression("[A-Z][0-9]{9}")]
public string ID { get; set; }
除了標準 Validation 的 DataAnnotation之外, DataAnnotation也可以客製化, 有些比較單純的資料關聯性的商業邏輯驗證, 就可以透過客製化的 DataAnnotation 來做驗證. 在 .NET 上客製 DataAnnotation, 相對來說算是比較簡單的, 基本上有兩個步驟: 一是繼承 ValidationAttribute 這個 Class, 二是改寫 IsValid 這個 Method.  下面這個例子, 我們對於 Room 物件加上限制條件, “如果 Room 物件的 Roomtype 是 Beach 的話, 則 Rate 必須大於 500”. 要實作這個驗證的 Annotation, 首先我們要先建立一個新的 Class, 稱之為 ScenicRoom, 程式碼如下
using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
{
    class ScenicRoom : ValidationAttribute
    {
        public ScenicRoom() { }
        protected override ValidationResult 
            IsValid(object value,
                    ValidationContext 
                           validationContext)
        {
            Room room = (Room)
                validationContext.ObjectInstance;
            if (room.Roomtype == "Beach" && 
                room.Rate <= 500)
            {
                return new ValidationResult(
                    "Beach room must > 500");
            }
            return ValidationResult.Success;
        }
    }
}
ScenicRoom 這個 Class 要繼承 ValidationAttribute, 並且要重新改寫 IsValid 這個 Method.  IsValid 這個 Method 有兩個參數, 第一個參數是要被驗證的值, 在下面程式碼的這個例子指的是 Rate 這個變數的值. 第二個參數則是執行驗證的環境. 在這個例子中, 我們是透過 ValidationContext 的物件 validationContext來取得 Room 的物件, 然後再對這個 Room 物件的 Roomtype 及 Rate 做驗證.  在完成客製化 DataAnnotation 的 Class 之後, 只需要把它加到要驗證的變數宣告之前即可, 如下面的程式所示.
using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
public partial class Room
    {
        [Required]
        public string RoomID { get; set; }
        [Required]
        [StringLength(6)]
        public string Roomtype { get; set; }
        [ScenicRoom]
        public Nullable<int> Rate { get; set; }
    }
當使用如下的頁面來新增(或修改)一個 Room 的物件時, 因為這個 Room 物件的 Roomtype 是 Beach, 但是 Rate 的值是 200, 也就是IsValid 第一個參數傳進來的值是 200, 而這個值小於等於 500, 因此會顯示出錯誤.



DataAnnotation 提供了一個簡單的方式, 可以在 Server 端對資料做驗證, 而且也可以延伸並客製化, 執行一些資料與資料之間的驗證規則, 因此可以減輕上層應用系統在資料驗證方面的負擔.
園丁的話:GSS Engineering Blog 滿週年了
善用 JIRA Dashboard,打造自己的 Free Style
 

評論

尚無評論
已經注冊了? 這裡登入
Guest
2024/05/20, 週一

Captcha 圖像