WebAPI- 自定義RequestModel 驗證

通常我們在後端接前端Request參數的時候,我們為了省事,會建立一個Model來將前後端Binding

儘管這樣的方式讓我們大幅減少了Action所需要的參數。

不過如果我們想要將每一個欄位都進行驗證的時候,此時光是Action內還沒寫主要程式碼,就先因為格式的驗證佔了一大半的程式碼

因此今天來介紹如何透過自定義Attribute來達到此目的。

 

首先一般來說我們在Model當中會定義像這樣的欄位來去接值:

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

   // 需超過20歲才可註冊
   public DateTime Birthday { get; set; }

   // 身分證
   public String IDCard { get; set; }
}

假設今天我們想要定義一些簡單的驗證,例如:

  1. 最小輸入長度
  2. 最大輸入長度
  3. Email驗證

那麼你只需要在上方新增一個標籤:

        // 必填資訊
        [MaxLength(10,ErrorMessage ="超過最大長度")] //設定最大只能輸入10個字,超過就回傳錯誤訊息
        public string Name { get; set; }

當標籤定義完之後,我們就可以在C#的程式讓他進行自動驗證

我們只需要這樣寫就可以自動幫我們做完驗證

if(ModelState.IsValid) //當Model驗證通過時就做的事情
{
  //Success do something
}
else{
//Failure do something
}

 

這樣的方式,讓我們在Action當中不會看到任何的欄位驗證邏輯。

不過這邊又有一個缺點:「官方預先寫好的太少」

因此接下來才是我們要學的重頭戲:

如何自訂義RequestModel 驗證

首先,我們需要先建立一個類別

根據官網文件,我們需要繼承 ValidationAttribute

並且去複寫 IsValid

此時會產生這樣的Code出來:

public override bool IsValid(object value)
{
    return  base.IsValid(value);
 }

接著我們就可以在裡面寫邏輯判斷拉!,其中這邊的value,是我們從前端傳進來的參數,因此我們就可以來寫判斷拉!

接下來我們來實做看看如何自定義身分證驗證,以下是程式碼:

public override bool IsValid(object value)
        {
            String ID = value.ToString().ToUpper();
            List<string> FirstEng = new List<string> { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "X", "Y", "W", "Z", "I", "O" };
            bool chackFirstEnd = false;
            if (ID.Trim().Length == 10)
            {
                byte firstNo = Convert.ToByte(ID.Trim().Substring(1, 1));
                if (firstNo > 2 || firstNo < 1)
                {
                    return false;
                }
                else
                {
                    int x;
                    for (x = 0; x < FirstEng.Count; x++)
                    {
                        if (ID.Substring(0, 1) == FirstEng[x])
                        {
                            ID = string.Format("{0}{1}", x + 10, ID.Substring(1, 9));
                            chackFirstEnd = true;
                            break;
                        }

                    }
                    if (!chackFirstEnd)
                        return false; 

                    int i = 1;
                    int ss = int.Parse(ID.Substring(0, 1));
                    while (ID.Length > i)
                    {
                        ss = ss + (int.Parse(ID.Substring(i, 1)) * (10 - i));
                        i++;
                    }
                    ID = ss.ToString();
                    if (value.ToString().Substring(9, 1) == "0")
                    {
                        if (ID.Substring(ID.Length - 1, 1) == "0")
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        if (value.ToString().Substring(9, 1) == (10 - int.Parse(ID.Substring(ID.Length - 1, 1))).ToString())
                        {

                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
            }
            else
            {

                return false;
            }
        }

接著在Action我們就可以這樣做囉!

 if(ModelState.IsValid)
           {
                return this.Json("Success"); //驗證過後回傳成功
            }
           else{

                var data = ModelState.Where(x => x.Value.Errors.Count > 0) //如果驗證失敗,則將錯誤訊息抓出來
                             .Select(x => new
                             {

                                 x.Key,
                                 x.Value.Errors[0].ErrorMessage

                             }).ToList();


                //   List<ModelState> data = ModelState.Values.ToList();
                return this.Json(data);

            }

這邊如果驗證失敗,我們則是採用linQ的方式,將ErrorMessage給取出來,至於細節部分在這邊就不攢述了

各位有興趣可以下中斷點看看回傳的內容,就可以明白為什麼我會這樣寫了。

 

以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教:)

有任何家教、案子 或技術相關問題 請都歡迎聯繫我

http://www.zhenghui.idv.tw/