關于這個想法,想看看歷史背景的,請移步 《數據驗證隨想》
今天要說的是這個組件在項目中的應用,以及后期對它的改善。在原來的想法中,希望做的大而全,結果越往后做,發現有點過度設計,寫完代碼后,樓主自己都懶得用。與其這么麻煩,還不如直接幾個 if 判斷完事。
既然如此,只能將問題簡單化。認真梳理一下樓主的需求:
1. 部分參數是必需的,驗證失敗,中斷,并返回該錯誤信息。
2. 部分參數是非必需的。驗證失敗就直接忽略。這個需求來自于,表單里部分值是可以空的,或者傳遞了意外的值,試圖忽略它。
3. 驗證成功后的參數,最好是能直接使用,而且類型都是轉換后的。
先看看代碼上是怎么調用的。
var v = ValidateHelp.BeginEntity<PumpCodeEntity>() .IsNullOrEmpty(form["tybh"], "統一編號", "未找到需要修改的數據") .IsInt(form["zldm"], "指令代碼", "指令代碼錯誤") .IsInt(form["sfyx"], "是否有效", "有效指令錯誤"); if (v.IsInValid) //數據無效 { return new ResultDTO() { Message = v.Message}; } ......其中form是MVC的FormCollection對象,沒用過的理解成HttPRequest也成。
PumpCodeEntity 是實體對象,呃,其中 “統一編號、指令代碼、是否有效” 是這個對象的屬性。為什么它會是中文,這個有項目背景,重點不是它啦。
大家可以看到,其中有3個驗證方法,方法帶有3個參數,分別是:
待驗證的值
Key名或屬性名(驗證成功存儲在Dictionary中, 或通過反射存儲在對象中)
錯誤消息提示 當未傳遞錯誤信息參數時,表示當前驗證的參數是非必需的。由于在驗證參數時,嘗試對參數做了類型轉換,故驗證成功后,參數的類型是正確的,將參數存儲到Dictionary<string,object>中,或者是對象的屬性中。
因此增加檢測條件時,只需要增加一個類型的判斷方法即可。代碼中已經內置了檢測整數、浮點數、雙精度、時間、正則等。
詳細代碼如下:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Text.RegularExpressions; 6 using CheckHandle = System.Func<Core.Data.ValidateHelp, string, string, string, Core.Data.ValidateHelp>; 7 namespace Core.Data 8 { 9 public class ValidateHelp 10 { 11 #region 屬性 12 //數據容器字典 13 public Dictionary<string, object> Data { get; protected set; } 14 //數據容器實體 15 public Object Entity { get; protected set; } 16 //錯誤信息 17 public string Message { get; protected set; } 18 /// <summary> 19 /// true:數據無效 false:數據有效 20 /// </summary> 21 private bool isInValid; 22 /// <summary> 23 /// true:數據無效 false:數據有效 24 /// </summary> 25 public bool IsInValid { get { return isInValid; } } 26 #endregion 27 28 #region 字段 29 30 //數據容器實體類型 31 protected Type EntityType; 32 //驗證委托緩存 33 private static Dictionary<string, CheckHandle> checkHandlers = new Dictionary<string, CheckHandle>(); 34 35 #endregion 36 37 #region 靜態方法 得到對象實例 38 public static ValidateHelp Begin() 39 { 40 var v = new ValidateHelp(); 41 v.Data = new Dictionary<string, object>(); 42 return v; 43 } 44 45 public static ValidateHelp BeginEntity<T>() 46 { 47 var v = new ValidateHelp(); 48 v.EntityType = typeof(T); 49 v.Entity = Activator.CreateInstance(v.EntityType); 50 return v; 51 } 52 #endregion 53 54 #region 私有輔助方法 55 private ValidateHelp() 56 { 57 } 58 59 60 private static ValidateHelp Error(ValidateHelp v, string msg) 61 { 62 //沒有錯誤信息 默認不修改驗證結果 63 if (msg == null || msg.Length == 0) 64 { 65 return v; 66 } 67 v.isInValid = true; 68 v.Message = msg; 69 return v; 70 } 71 72 private static ValidateHelp Success(ValidateHelp v, object value, string propertyName) 73 { 74 if (v.IsInValid) return v; 75 if (propertyName != null && propertyName.Length > 0) 76 { 77 if (v.Data != null) 78 { 79 v.Data[propertyName] = value; 80 } 81 else if (v.Entity != v) 82 { 83 var p = v.Entity.GetType().GetProperty(propertyName); 84 //為對象屬性賦值 85 p.SetValue(v.Entity, value, null); 86 } 87 } 88 return v; 89 } 90 91 private ValidateHelp Check(string[] args, CheckHandle fun) 92 { 93 if (args == null || args.Length == 0 || args.Length > 3) 94 { 95 throw new Exception("驗證參數錯誤"); 96 } 97 //如果之前驗證失敗,就直接返回 98 if (isInValid) return this; 99 var value = args[0];100 var propertyName = args.Length > 1 ? args[1] : null;101 var msg = args.Length > 2 ? args[2] : null;102 return fun(this, value, propertyName, msg);103 }104 105 #endregion106 107 #region 公有輔助方法108 public object this[string key]109 {110 get111 {112 object o;113 if (Data.TryGetValue(key, out o)) return o;114 return null;115 }116 }117 #endregion118 119 #region 驗證方法120 public virtual ValidateHelp IsNullOrEmpty(params string[] args)121 {122 CheckHandle handler;123 if (!checkHandlers.TryGetValue("IsNullOrEmpty", out handler))124 {125 handler = (scope, s, p, m) =>126 {127 if (s == null || s.Length == 0)128 {129 return Error(scope, m);130 }131 return Success(scope, s, p);132 };133 checkHandlers["IsNullOrEmpty"] = handler;134 };135 return Check(args, handler);136 }137 public virtual ValidateHelp IsInt(params string[] args)138 {139 CheckHandle handler;140 if (!checkHandlers.TryGetValue("IsInt", out handler))141 {142 handler = (scope, s, p, m) =>143 {144 int i;145 if (!int.TryParse(s, out i))146 {147 return Error(scope, m);148 }149 return Success(scope, i, p);150 };151 checkHandlers["IsInt"] = handler;152 };153 return Check(args, handler);154 }155 156 public virtual ValidateHelp IsDouble(params string[] args)157 {158 CheckHandle handler;159 if (!checkHandlers.TryGetValue("IsDouble", out handler))160 {161 handler = (scope, s, p, m) =>162 {163 double i;164 if (!double.TryParse(s, out i))165 {166 return Error(scope, m);167 }168 return Success(scope, i, p);169 };170 checkHandlers["IsDouble"] = handler;171 };172 return Check(args, handler);173 }174 175 public virtual ValidateHelp IsLong(params string[] args)176 {177 CheckHandle handler;178 if (!checkHandlers.TryGetValue("IsLong", out handler))179 {180 handler = (scope, s, p, m) =>181 {182 long i;183 if (!long.TryParse(s, out i))184 {185 return Error(scope, m);186 }187 return Success(scope, i, p);188 };189 checkHandlers["IsLong"] = handler;190 };191 return Check(args, handler);192 }193 194 public virtual ValidateHelp IsFloat(params string[] args)195 {196 Che
新聞熱點
疑難解答