Smark.Data实体成员数据验证

 

       Smark.Data支持通过Atteribute的方式来描述一个实体对象在数据保存前进行数据的有效验证,使用人员也可以通过扩展自己的Attribute实现新的验证方式。下面介绍一下这个验机制的实现和扩展。

       Smark.Data中所有实体必须继承DataObject,这个对象主要包装了一些简单的实体操作(详细代码可以到: http://smark.codeplex.com/ 获取)。先看一下DataObject数据添加的代码:

private void NewData(IConnectinContext cc, ObjectMapper om)

        {

            Insert insert = new Insert(om.Table);

            object value = null;

            if (om.ID != null)

            {

                if (om.ID.Value != null)

                {

                    if (!om.ID.Value.AfterByUpdate)

                    {

                        om.ID.Value.Executing(cc, this, om.ID,om.Table);

                        insert.AddField(om.ID.ColumnName, om.ID.Handler.Get(this));

                    }

                }

                else

                {

                    insert.AddField(om.ID.ColumnName, om.ID.Handler.Get(this));

                }

            }

            foreach (PropertyMapper pm in om.Properties)

            {

                if (!EntityState._FieldState.ContainsKey(pm.Handler.Property.Name))

                {

                    if (pm.Value != null && !pm.Value.AfterByUpdate)

                    {

                        pm.Value.Executing(cc, this, pm, om.Table);

                    }

                }

                value = pm.Handler.Get(this);

                foreach (Validates.ValidaterAttribute val in pm.Validaters)

                {

                    val.Validating(value, this, pm, cc);

                }

                if (EntityState._FieldState.ContainsKey(pm.Handler.Property.Name))

                {

                    if (pm.Cast != null)

                    {

 

                        value = pm.Cast.ToColumn(value, pm.Handler.Property.PropertyType, this);

                    }

                    insert.AddField(pm.ColumnName, value);

                }

            }

            insert.Execute(cc);

            if (om.ID != null && om.ID.Value != null && om.ID.Value.AfterByUpdate)

                om.ID.Value.Executed(cc, this, om.ID,om.Table);

        }

红色部分代码部分描述,如果当属性存在验证描述的情况,就执行相关验证;实际情况下有可能一个属性配置多个验证的,如:不能为空,范围值等等。

首先定义一个验证基础类来描述需要干什么。

    [AttributeUsage(AttributeTargets.Property)]

    public abstract class ValidaterAttribute : Attribute

    {

        public void Validating(object value, object source,Mappings.PropertyMapper pm,IConnectinContext cc )

        {

            if (!OnValidating(value, source, pm,cc))

                throw new ValidaterException(Message);

        }

 

        protected abstract bool OnValidating(object value, object source, Mappings.PropertyMapper pm, IConnectinContext cc);

 

        public string Message

        {

            get;

            set;

        }

 

    }

既然明确了要干什么,那下面就好扩展了。

不为空

    [AttributeUsage(AttributeTargets.Property)]

    public class NotNull : ValidaterAttribute

    {

        public NotNull(string message)

        {

            Message = message;

        }

        protected override bool OnValidating(object value, object source, Mappings.PropertyMapper pm, IConnectinContext cc)

        {

            return value != null && !string.IsNullOrEmpty(value.ToString());

        }

    }

长度限制

    [AttributeUsage(AttributeTargets.Property)]

    public class Length : ValidaterAttribute

    {

 

        public Length(string min, string max, string message)

        {

            if (!string.IsNullOrEmpty(min))

                MinLength = int.Parse(min);

            if (!string.IsNullOrEmpty(max))

                MaxLength = int.Parse(max);

            Message = message;

        }

        public int? MinLength

        {

            get;

            set;

        }

        public int? MaxLength

        {

            get;

            set;

        }

        protected override bool OnValidating(object value, object source, Mappings.PropertyMapper pm, IConnectinContext cc)

        {

          

            if (value != null && !string.IsNullOrEmpty(value.ToString()))

            {

                string data = Convert.ToString(value);

                if (MinLength != null && MinLength > data.Length)

                {

 

                    return false;

                }

 

                if (MaxLength != null && data.Length > MaxLength)

                {

 

                    return false;

 

                }

            }

            return true;

        }

     

    }

正则

    [AttributeUsage(AttributeTargets.Property)]

    public class Match : ValidaterAttribute

    {

        public Match(string regex, string message)

        {

            Regex = regex;

            Message = message;

        }

        public string Regex

        {

            get;

            set;

        }

        protected override bool OnValidating(object value, object source, Mappings.PropertyMapper pm, IConnectinContext cc)

        {

          

            if (value != null && !string.IsNullOrEmpty(value.ToString()))

            {

                string data = Convert.ToString(value);

                if (System.Text.RegularExpressions.Regex.Match(

                    data, Regex, RegexOptions.IgnoreCase).Length == 0)

                {

                    return false;

                }

 

            }

            return true;

        }

      

    }

    [AttributeUsage(AttributeTargets.Property)]

    public class EMail : Match

    {

        public EMail(string msg) : base(@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", msg) { }

    }

    [AttributeUsage(AttributeTargets.Property)]

    public class CardID : Match

    {

        public CardID(string msg) : base(@"^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$/", msg) { }

    }

当然还可以通过查询数据库进行验证

    [AttributeUsage(AttributeTargets.Property)]

    public class Unique : ValidaterAttribute

    {

        public Unique(string err)

        {

            Message = err;

        }

        protected override bool OnValidating(object value, object source, Mappings.PropertyMapper pm, IConnectinContext cc)

        {

            if (value == null)

                return true;

            if (string.IsNullOrEmpty((string)value))

                return true;

            string sql = "select {0} from {1} where {0}=@p1";

            Command cmd = new Command(string.Format(sql, pm.ColumnName, pm.OM.Table));

            cmd.AddParameter("p1", value);

            object result = cc.ExecuteScalar(cmd);

            return result == null || result == DBNull.Value;

 

        }

    }

对于使用也很简单

        /// <summary>

        /// 用户名称

        /// </summary>

        [Column]

        [NotNull("用户名不能为空!")]

        [Length("5", "16", "用户名长度必须5-16个字符!")]

        [Unique("该用户名已经给其他用户使用!")]

        string UserName { get; set; }

 

posted on 2009-09-15 14:07  henry  阅读(1948)  评论(5编辑  收藏  举报

导航