CODE-使用ValidationAttribute檢核資料
| | 3 | | 11,830 |
在ASP.NET MVC 3 豬走路範例(2)裡介紹過ASP.NET MVC可以識別Model屬性(Property)上的DataAnnotation ValidationAttribute,例如: [Required][Range(…)],自動在表單輸入介面加上檢核函數,更新資料時也可用同一邏輯進行伺服器資料檢核,不用再像以前Client、Server各寫一次,也不容易因開發人員疏忽而錯放無效資料,十分方便可靠。
遇到個需求,在Console程式中引用為ASP.NET MVC開發的Model DLL,在修改完Model的屬性內容後,也想用Model上各屬性所標註的[Required][Range()] ValidationAttribute進行資料驗證。
System.ComponentModel.DataAnnotations內建了Validator Class可以幫我們實現這個理想,我整理成簡單的程式範例:
using System;
using System.Collections.Generic;
using Autofac;
using System.ComponentModel.DataAnnotations;
namespace AutofacLab
{
class Program
{
static void Main(string[] args)
{
BooModel boo = new BooModel(); //故意不給Name
ShowValidationResult(boo);
boo.Name = "Jeffrey Lee"; //故意讓Name過長
boo.Score = 65535; //故意讓數字超出範圍
ShowValidationResult(boo);
boo.Name = "Jeffrey";
boo.Score = 32767;
ShowValidationResult(boo);
Console.Read();
}
static void ShowValidationResult(BooModel boo)
{
ValidationContext vldCtx =
new ValidationContext(boo, null, null);
List<ValidationResult> errors =
new List<ValidationResult>(); //檢核錯誤會被放入集合
//注意第四個參數,要填true,才會檢核Required以外的ValidationAttribute
//參數名稱(validateAllProperties)有誤導之嫌
//已有網友在Connect反應: http://goo.gl/zllLw
bool succ = Validator.TryValidateObject(boo, vldCtx, errors, true);
Console.WriteLine("Boo {{ Name:{0} Score:{1} }}",
boo.Name, boo.Score);
Console.WriteLine("Pass? {0}", succ);
foreach (ValidationResult r in errors)
Console.WriteLine(" - Error: {0}", r.ErrorMessage);
}
}
class BooModel
{
[Required(ErrorMessage = "Name is required")]
[StringLength(8, ErrorMessage = "Max length = 8")]
public string Name { get; set; }
[Range(0, 32767, ErrorMessage = "Range = 0-32767")]
public int Score { get; set; }
}
}
執行結果為:
Boo { Name: Score:0 }
Pass? False
- Error: Name is required
Boo { Name:Jeffrey Lee Score:65535 }
Pass? False
- Error: Max length = 8
- Error: Range = 0-32767
Boo { Name:Jeffrey Score:32767 }
Pass? True
補充一點,測試這段程式時,踩到一枚小地雷。
經測試,想要完整觸發所有的ValidationAttribute,得使用 Validator.TryValidateObject Method (Object, ValidationContext, ICollection<ValidationResult>, Boolean),並在第四個參數傳入true,才會檢核[Required]以外的ValidationAttribute,這跟參數名稱(validateAllProperties)與文件所說"如果 validateAllProperties 設定為 true,此方法會驗證物件之屬性 (Property) 全部的值。"有點出入,已有網友回報Microsoft Connect此一問題,官方的回覆也證實此點(Thanks for the suggestion. Unfortunately now with named parameters as a feature in the compiler even renaming a parameter can become a breaking change. Due to this will have to leave the property named as it is.) 在應用時要留意。
Comments
# by David.net
又學到一招了 之前我還自己寫檢查 DataAnnotations 的語法 卻沒發現原來有現成的工具阿 昏了~~ 謝謝
# by jain
這看起來也可用在一般的AP,不只ASP.NET嗎?
# by Jeffrey
to jain, Yes, DataAnnotations被歸在System.ComponentModel,並不是ASP.NET的專利,例如在Silverlight裡也可應用,而文中的範例是用Console Application來跑的。