在方法中,為了保證數(shù)據(jù)的有效性,難免對(duì)它做檢查,在參數(shù)多的時(shí)候,if判斷就會(huì)很多。示例代碼如下:
public ActionResult Login(string uid, string pwd) { ResultDTO rdto = new ResultDTO(); if (uid == null || uid.Length == 0) { rdto.Message = "用戶名不能為空"; return this.Json(rdto); } if (pwd == null || pwd.Length == 0) { rdto.Message = "密碼不能為空"; return this.Json(rdto); } ... }這僅僅是2個(gè)字段進(jìn)行非空驗(yàn)證,如果是字段多,而且驗(yàn)證方式更多,則難免也寫N個(gè)if判斷。
MVC中提供了驗(yàn)證機(jī)制,在實(shí)體上添加Attrbute即可指明驗(yàn)證參數(shù)的方法。但是很多時(shí)候參數(shù)是不固定的呀,多變的,比如說查詢條件,少則三四個(gè),多則十幾個(gè),更多的也有。所以在驗(yàn)證參數(shù)這一塊,還不知道有什么方法可以簡(jiǎn)化我們的工作量,如果有朋友知道,還請(qǐng)告知,先謝過。
來說說樓主的方法,目前僅在猜想中,未應(yīng)用于任何項(xiàng)目。
先看看樓主的調(diào)用方式:
using System;using System.Collections.Generic;using System.Collections.Specialized;using System.Diagnostics;using System.Linq;using System.Text;using System.Text.RegularExPRessions;using System.Web;namespace MacRead{ class Program { static void Main(string[] args) { //參數(shù)格式:模仿MVC中的FormValueCollection,或Request["xxx"] var form = new NameValueCollection(); form["UserName"] = "admin"; form["passWord"] = "*********"; form["Sex"] = "2"; //form["Sex"] = null; form["Email"] = "304885433@QQ.com"; /* 指明必須驗(yàn)證的字段 驗(yàn)證數(shù)據(jù) 自動(dòng)填充Model */ var Request = HttpContext.Current.Request; var v = ValidateHelp.BeginEntity<User>() .Require("UserName", "password", "Email", "Sex") .IsNullOrEmpty(form["UserName"], "用戶名不能為空") .IsNullOrEmpty(form["password"], "密碼不能為空", "password") .IsInt(form["Sex"], "無(wú)法識(shí)別性別", "Sex") .IsEmail(form["Email"], "郵箱地址錯(cuò)誤", "Email"); if (v.IsValid) { Console.WriteLine("驗(yàn)證通過"); var m = v.Entity as User; } else { Console.WriteLine("驗(yàn)證未通過 信息:" + v.ErrorMsg); } /* 驗(yàn)證數(shù)據(jù) 自動(dòng)填充Dictionary */ form["Email"] = "304885433"; v = ValidateHelp.BeginDic() .Require("UserName", "password", "Email", "Sex") .IsNullOrEmpty(form["UserName"], "用戶名不能為空", "UserName") .IsNullOrEmpty(form["password"], "密碼不能為空", "password") .IsInt(form["Sex"], "無(wú)法識(shí)別性別", "Sex") .IsEmail(form["Email"], "郵箱地址錯(cuò)誤", "Email"); if (v.IsValid) { Console.WriteLine("驗(yàn)證通過"); } else { Console.WriteLine("驗(yàn)證未通過 信息:" + v.ErrorMsg); } foreach (var d in v.Data) { Console.WriteLine("{0}={1}", d.Key, d.Value); } } } public class User { public string UserName { get; set; } public string password { get; set; } public int Sex { get; set; } public string Email { get; set; } }}
定義了一個(gè)ValidateHelp 對(duì)象,在初始化的時(shí)候,可以選擇數(shù)據(jù)容器。
解釋一下,為什么需要數(shù)據(jù)容器。我們?cè)诜椒ㄩ_始對(duì)參數(shù)做驗(yàn)證,驗(yàn)證通過后必然是要去使用它,使用時(shí)難免需要類型轉(zhuǎn)換,所以干脆在驗(yàn)證的時(shí)候去指明一個(gè)數(shù)據(jù)容器,在數(shù)據(jù)驗(yàn)證通過后,將數(shù)據(jù)填充到指定的容器中即可,驗(yàn)證完畢后,直接取出來使用。
看看其中一個(gè)驗(yàn)證方法的定義。
public ValidateHelp IsNullOrEmpty(string s, string msg = null, string propertyName = null)
s:被驗(yàn)證的字符串
msg:驗(yàn)證失敗的提示消息
propertyName:驗(yàn)證成功后保存的屬性名稱,當(dāng)數(shù)據(jù)容器為Dictionary時(shí)為Key,當(dāng)數(shù)據(jù)容器為Model時(shí)為屬性名。
所以樓主的目的就是驗(yàn)證失敗時(shí),得到錯(cuò)誤信息,驗(yàn)證成功,能自動(dòng)把類型變換后的值保存。
由于上面說了,目前還在猜想階段,在對(duì)實(shí)體進(jìn)行賦值時(shí),使用的是反射。
性能要求不高的場(chǎng)景下,用反射即可,要求高的時(shí)候,推薦一個(gè)朋友寫的庫(kù),在整個(gè)軟件生命周期,調(diào)用次數(shù)達(dá)到1w以上,性能十分強(qiáng)勁,大家可以看看,《Literacy 快速反射讀寫對(duì)象屬性,字段》
樓主在原來的項(xiàng)目中做查詢,條件總數(shù)大概有十幾個(gè),其中4-5個(gè)是必需的,其他為null時(shí)可以忽略,加入Require方法,目的則是指明部分屬性是不可以為null的。在上面的實(shí)例中,對(duì)于Sex字段驗(yàn)證時(shí),該值為null,最后依然驗(yàn)證通過。
源碼如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Text.RegularExpressions;namespace MacRead{ public class ValidateHelp { #region 屬性 //數(shù)據(jù)容器字典 public Dictionary<string, object> Data { get; private set; } //數(shù)據(jù)容器實(shí)體 public Object Entity { get; private set; } //錯(cuò)誤信息 public string ErrorMsg { get; private set; } // true:驗(yàn)證通過 false:驗(yàn)證未通過 public bool IsValid { get; private set; } #endregion #region 字段 //數(shù)據(jù)容器實(shí)體類型 private Type EntityType; //必需的字段信息 private string[] RequiredProperty; #endregion #region 靜態(tài)方法 得到對(duì)象實(shí)例 public static ValidateHelp Begin() { return new ValidateHelp(); } public static ValidateHelp BeginDic() { var v = new ValidateHelp(); v.Data = new Dictionary<string, object>(); return v; } public static ValidateHelp BeginEntity<T>() { var v = new ValidateHelp(); v.EntityType = typeof(T); v.Entity = Activator.CreateInstance(v.EntityType); return v; } #endregion #region 輔助方法 public object this[string key] { get { object o; if (Data.TryGetValue(key, out o)) return o; return null; } } /// <summary> /// 指明必需的屬性 不允許為null /// </summary> /// <param name="requiredProperty"></param> /// <returns></returns> public ValidateHelp Require(params string[] requiredProperty) { if (this.RequiredProperty != null) throw new Exception("Require can‘t be called multiple times "); this.RequiredProperty = requiredProperty; return this; } #endregion #region 私有方法 private ValidateHelp() { IsValid = true;//默認(rèn)驗(yàn)證通過 } /// <summary> /// 數(shù)據(jù)驗(yàn)證不通過 /// </summary> /// <param name="msg">錯(cuò)誤信息提示</param> /// <returns></returns> private ValidateHelp SetInValid(string msg) { IsValid = false; ErrorMsg = msg; return this; } /// <summary> /// 數(shù)據(jù)驗(yàn)證通過 /// </summary> /// <param name="value">數(shù)據(jù)</param> /// <param name="propertyName">屬性名</param> /// <returns></returns> private ValidateHelp SetValid(object value, string propertyName) { if (!IsValid) IsValid = true; if (propertyName != null && propertyName.Length > 0) { if (Data != null) { Data[propertyName] = value; } else if (Entity != null) { var p = Entity.GetType().GetProperty(propertyName); //為對(duì)象屬性賦值 p.SetValue(Entity, value, null); } } return this; } /// <summary> /// 驗(yàn)證檢查 返回True 終止驗(yàn)證,false 繼續(xù)驗(yàn)證 /// </summary> /// <param name="s">輸入值</param> /// <param name="propertyName">屬性值</param> /// <returns></returns> private bool Interrupt(string s, string propertyName) { //驗(yàn)證無(wú)效,直接返回 if (!IsValid) return true; /*繼續(xù)驗(yàn)證條件 * s非空 * 未指明屬性名 * 未定義必需的屬性 */ if (s != null || propertyName == null || propertyName.Length == 0 || RequiredProperty == null ||
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注