在方法中,为了保证数据的有效性,难免对它做检查,在参数多的时候,if判断就会很多。示例代码如下:
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个字段进行非空验证,如果是字段多,而且验证方式更多,则难免也写N个if判断。
MVC中提供了验证机制,在实体上添加Attrbute即可指明验证参数的方法。但是很多时候参数是不固定的呀,多变的,比如说查询条件,少则三四个,多则十几个,更多的也有。所以在验证参数这一块,还不知道有什么方法可以简化我们的工作量,如果有朋友知道,还请告知,先谢过。
来说说楼主的方法,目前仅在猜想中,未应用于任何项目。
先看看楼主的调用方式:
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) { //参数格式:模仿MVC中的FormValueCollection,或Request["xxx"] var form = new NameValueCollection(); form["UserName"] = "admin"; form["passWord"] = "*********"; form["Sex"] = "2"; //form["Sex"] = null; form["Email"] = "304885433@QQ.com"; /* 指明必须验证的字段 验证数据 自动填充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"], "无法识别性别", "Sex") .IsEmail(form["Email"], "邮箱地址错误", "Email"); if (v.IsValid) { Console.WriteLine("验证通过"); var m = v.Entity as User; } else { Console.WriteLine("验证未通过 信息:" + v.ErrorMsg); } /* 验证数据 自动填充Dictionary */ form["Email"] = "304885433"; v = ValidateHelp.BeginDic() .Require("UserName", "password", "Email", "Sex") .IsNullOrEmpty(form["UserName"], "用户名不能为空", "UserName") .IsNullOrEmpty(form["password"], "密码不能为空", "password") .IsInt(form["Sex"], "无法识别性别", "Sex") .IsEmail(form["Email"], "邮箱地址错误", "Email"); if (v.IsValid) { Console.WriteLine("验证通过"); } else { Console.WriteLine("验证未通过 信息:" + 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; } }}
定义了一个ValidateHelp 对象,在初始化的时候,可以选择数据容器。
解释一下,为什么需要数据容器。我们在方法开始对参数做验证,验证通过后必然是要去使用它,使用时难免需要类型转换,所以干脆在验证的时候去指明一个数据容器,在数据验证通过后,将数据填充到指定的容器中即可,验证完毕后,直接取出来使用。
看看其中一个验证方法的定义。
public ValidateHelp IsNullOrEmpty(string s, string msg = null, string propertyName = null)
s:被验证的字符串
msg:验证失败的提示消息
propertyName:验证成功后保存的属性名称,当数据容器为Dictionary时为Key,当数据容器为Model时为属性名。
所以楼主的目的就是验证失败时,得到错误信息,验证成功,能自动把类型变换后的值保存。
由于上面说了,目前还在猜想阶段,在对实体进行赋值时,使用的是反射。
性能要求不高的场景下,用反射即可,要求高的时候,推荐一个朋友写的库,在整个软件生命周期,调用次数达到1w以上,性能十分强劲,大家可以看看,《Literacy 快速反射读写对象属性,字段》
楼主在原来的项目中做查询,条件总数大概有十几个,其中4-5个是必需的,其他为null时可以忽略,加入Require方法,目的则是指明部分属性是不可以为null的。在上面的实例中,对于Sex字段验证时,该值为null,最后依然验证通过。
源码如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Text.RegularExpressions;namespace MacRead{ public class ValidateHelp { #region 属性 //数据容器字典 public Dictionary<string, object> Data { get; private set; } //数据容器实体 public Object Entity { get; private set; } //错误信息 public string ErrorMsg { get; private set; } // true:验证通过 false:验证未通过 public bool IsValid { get; private set; } #endregion #region 字段 //数据容器实体类型 private Type EntityType; //必需的字段信息 private string[] RequiredProperty; #endregion #region 静态方法 得到对象实例 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;//默认验证通过 } /// <summary> /// 数据验证不通过 /// </summary> /// <param name="msg">错误信息提示</param> /// <returns></returns> private ValidateHelp SetInValid(string msg) { IsValid = false; ErrorMsg = msg; return this; } /// <summary> /// 数据验证通过 /// </summary> /// <param name="value">数据</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); //为对象属性赋值 p.SetValue(Entity, value, null); } } return this; } /// <summary> /// 验证检查 返回True 终止验证,false 继续验证 /// </summary> /// <param name="s">输入值</param> /// <param name="propertyName">属性值</param> /// <returns></returns> private bool Interrupt(string s, string propertyName) { //验证无效,直接返回 if (!IsValid) return true; /*继续验证条件 * s非空 * 未指明属性名 * 未定义必需的属性 */ if (s != null || propertyName == null || propertyName.Length == 0 || RequiredProperty == null ||
新闻热点
疑难解答