惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
Spread Privacy
Spread Privacy
Google DeepMind News
Google DeepMind News
WordPress大学
WordPress大学
Blog — PlanetScale
Blog — PlanetScale
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
SecWiki News
SecWiki News
腾讯CDC
P
Privacy International News Feed
Webroot Blog
Webroot Blog
J
Java Code Geeks
爱范儿
爱范儿
A
About on SuperTechFans
S
Secure Thoughts
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
D
DataBreaches.Net
Cloudbric
Cloudbric
Security Archives - TechRepublic
Security Archives - TechRepublic
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Proofpoint News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Security Latest
Security Latest
Forbes - Security
Forbes - Security
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
Cybersecurity and Infrastructure Security Agency CISA
T
Threatpost
量子位
MongoDB | Blog
MongoDB | Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Vercel News
Vercel News
Google Online Security Blog
Google Online Security Blog
云风的 BLOG
云风的 BLOG
GbyAI
GbyAI
S
Security @ Cisco Blogs
T
The Exploit Database - CXSecurity.com
Help Net Security
Help Net Security
V
Visual Studio Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 聂微东
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
Attack and Defense Labs
Attack and Defense Labs

博客园 - henry

Smark.Net.Tcp.XmlService性能测试程序 基于Flex的http简易文件管理工具 性能的瓶颈到底在那呢? 运用Smark.SocketAsyncs扩展基于XML的TCP服务 运用Smark.SocketAsyncs方便实现数据交互服务 实现分布式对象锁 发布一个C#实现的Asterisk的管理系统 asterisk使用SIP相互对接 开源一个基于Flex4+C#的个人信息管理程序 FlashBuilder4试用 这样的重构是否有必要呢? Asterisk2B用户管理逻辑设计 用JQuery UI dialog实现Alert和Confirm功能 - henry Asterisk发起电话预约回拔 WOW工会DKP管理系统 我的分页控件设计 实现一个JavaScript验证的Asp.net Helper - henry - 博客园 Smark.Data 实体属性值描述 Smark.Data Part1
Smark.Data实体成员数据验证
henry · 2009-09-15 · via 博客园 - henry
 

       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; }