通常我們在後端接前端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; }
}
假設今天我們想要定義一些簡單的驗證,例如:
- 最小輸入長度
- 最大輸入長度
- 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給取出來,至於細節部分在這邊就不攢述了
各位有興趣可以下中斷點看看回傳的內容,就可以明白為什麼我會這樣寫了。
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教:)
有任何家教、案子 或技術相關問題 請都歡迎聯繫我