首页 > 学院 > 开发设计 > 正文

数据验证随想

2019-11-17 01:30:42
字体:
来源:转载
供稿:网友

数据验证随想

前言

  在方法中,为了保证数据的有效性,难免对它做检查,在参数多的时候,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 快速反射读写对象属性,字段》

说说Require

  楼主在原来的项目中做查询,条件总数大概有十几个,其中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 ||
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表