用特性来实现数据的校验

在网站开发中,往往需要对用户输入的数据进行校验。
而为了保持数据的完整性,我们需要进行客户端和服务端的双重校验。
客户端的校验一般由js来完成,本文主要介绍利用特性完成服务器端的数据校验。

什么是特性?

超市中有各种各样的商品,商品上贴有标签。标签上可能有商品的名称,价格,种类等信息。我们要购买一样东西前,一般先会看标签,了解更多的信息。当然主要是价格,万一钱没带够呢?:)
如果把类当做商品,那么特性就是贴在商品上的标签。特性给我们提供了更多类相关的信息。[Serializable] 就是在C#中常用的一个系统的特性,通过这个特性,我们可以知道类是否允许被序列化。

特性验证简单Demo

我们已经了解了特性,那么如何用特性校验数据呢?
假设用户注册后,通过客户端的校验后,将用户名和密码传输到了服务器。我们先验证用户名不为空,怎么做呢?
理一下思路,我们可以分3步来完成这件事情:
1、声明一个自定义特性。
2、给用户类添加自定义特性。
3、通过特性实现对数据的校验。

声明一个自定义特性。

 1     [AttributeUsage(AttributeTargets.Property)]
 2     class RequiredAttribute : Attribute
 3     {
 4         /// <summary>
 5         /// 验证失败返回的错误信息
 6         /// </summary>
 7         public string ErrorMessage
 8         {
 9             get;
10             set;
11         }
12
13         /// <summary>
14         /// 输入值
15         /// </summary>
16         public object InputValue
17         {
18             get;
19             set;
20         }
21
22         /// <summary>
23         /// 验证规则
24         /// </summary>
25         /// <param name="errorMessage">验证失败返回的错误信息</param>
26         public RequiredAttribute(string errorMessage)
27         {
28             this.ErrorMessage = errorMessage;
29         }
30
31         /// <summary>
32         /// 接口参数为空或空字符串都返回false
33         /// </summary>
34         /// <returns></returns>
35         public  bool Validate()
36         {
37             return !string.IsNullOrEmpty(InputValue.ToString());
38         }
39
40     }

自定义特性必须继承Attribute类,[AttributeUsage(AttributeTargets.Property)]特性表示,我们自定义的特性,只允许添加到类的属性上。Validate()方法就是这个特性的核心逻辑,他的功能很简单,验证用户输入的值是否为空。 这个值从哪儿来呢?别急,我们一步步来。

给用户类添加自定义特性

public class User
{
    [Required("请输入用户名")]
    public string UserName { get; set; }
    public string PassWord { get; set; }
}

特性可添加在类,属性,方法,字段上。这里添加到属性上是因为我们仅需要对属性的值进行校验,且我们自定义特性时声明了特性只能添加到属性上。 [Required("请输入用户名")],我们发现特性声明就是对特性类进行实例化,圆括弧中需要传入的参数,就是我们声明构造函数时的参数。其实自定义特性就相当于超市中用于贴标签的机器。

通过特性实现对数据的校验。

我们通过读商品的标签就可以知道商品的信息,然后决定是不是要买。同样用户类中的特性也需要一个人来读,我们肯定读不了这个特性,那么找谁来做呢?没错,反射。

public string Validate()
{
    // 反射取当前对象的所有属性
    System.Reflection.PropertyInfo[] properties = this.GetType().GetProperties();
    foreach (var pInfo in properties)
    {
        // 取属性中的特性
        if (pInfo.IsDefined(typeof(RequiredAttribute),false))
        {
            var customAttributes =
                pInfo.GetCustomAttributes(typeof (RequiredAttribute), false) as RequiredAttribute[];
            // 根据特性进行参数验证
            foreach (var attribute in customAttributes)
            {
                // 初始化特性,并进行验证。
                var validateVal = pInfo.GetValue(this, null);
                attribute.InputValue = validateVal;
                if (!attribute.Validate())
                {
                    return "验证失败!消息:" + attribute.ErrorMessage;
                }
            }
        }
    }
    // 验证成功
    return "验证成功!";
}

代码的注释已经很清楚了,就不在解释代码了。
还记得我们前面有个问题:用户输入的值的初始化问题么?其实值就是反射取属性的值,交给我们的特性。

总结

到这儿我们再回头看整个特性验证的过程其实很简单。原来我们验证是每来一个数据都自己写单独的逻辑去验证。而现在,我们将验证的逻辑封装到特性内,哪个数据需要就添加这个特性。数据校验时,我们只需反射用特性来做校验就可以了。再打个比方:我们在小摊上买东西的时候,每种商品我们都需去询问摊主,这个买多少钱啊?而超市给每种商品都贴上了标签,明码标价。

时间: 2024-08-13 21:32:06

用特性来实现数据的校验的相关文章

可视化接口管理工具RAP,模拟数据,校验接口

最近看到一个不错的接口管理的工具,分享一下 RAP ppt介绍:http://www.imooc.com/video/11060 RAP是一个可视化接口管理工具 通过分析接口结构,动态生成模拟数据,校验真实接口正确性, 围绕接口定义,通过一系列自动化工具提升我们的协作效率. 使用网址:http://rap.taobao.org/ GitHub地址:https://github.com/thx/RAP 一些文档:https://github.com/thx/RAP/wiki/home_cn 官网:

Atitit.&#160;数据约束&#160;校验&#160;原理理论与&#160;架构设计&#160;理念模式java&#160;php&#160;c#.net&#160;js&#160;javascript&#160;mysql&#160;oracle

Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq  index2 3. 检查约束 (Check Counstraint) 对该列数据的范围.格式的限制(如:年龄.性别等)2 4. 默认约束 (Default Counstraint) 该数据的默认值2 5. trigger2 6. 外键机制  参照完整性:2 7. 断言约束:不必与特定的列绑定,可以理解为能应用于多个表的

选择子数据,默认存储父数据 的校验方法

如下图:选择了子数据,默认选中父级数据,数据库中会存储两条数据 为使脚本通用性更好,不写死两级,可将数据放到List里处理,代码如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36     String companyName = null;     companyName = "测试公司1.1";      stepInfo(&q

Android应用开发中如何使用RSA加密算法对数据进行校验

这个世界很精彩,这个世界很无奈.是的,在互联网时代,如何保护自己的数据,如何对数据进行加密和效验就变得非常的重要.这里总结一下Android平台使用Java语言,利用RSA算法对数据进行校验的经验. 先来看下如何RSA加密算法对数据进行校验的流程: 1.首先要用openssh之类的程序生成一个私钥 2.再根据私钥生成一个公钥 3.使用私钥和公钥,对数据进行签名,得到签名文件. 4.使用公钥和签名文件就可以对数据进行校验了. 再来看下如何实现: 1.生成2048位的私钥: openssl genr

经典的MySQL 数据备份校验daemon程序

# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 Justin Santa Barbara # All Rights Reserved. # Copyright

利用字符串和十进制逢10进位的特性实现大数据的算术运算。(加法案例)

java中普通的数据类型int,long等不支持大数据间的算术运算,会出现丢失精度的问题,甚至无法用现有数据类型表示. 例如:对这两个数做加法运算:1243543534646546546465465465464654+32423985348957348957348957348957348574=? 在java中Long类型已经无法表示了,Long类型的最大值为Long.MAX_VALUE=9223372036854775807. 但jdk类库中提供了BigInteger类型,可以解决. 这里我用

HDFS源码分析数据块校验之DataBlockScanner

DataBlockScanner是运行在数据节点DataNode上的一个后台线程.它为所有的块池管理块扫描.针对每个块池,一个BlockPoolSliceScanner对象将会被创建,其运行在一个单独的线程中,为该块池扫描.校验数据块.当一个BPOfferService服务变成活跃或死亡状态,该类中的blockPoolScannerMap将会更新. 我们先看下DataBlockScanner的成员变量,如下: // 所属数据节点DataNode实例 private final DataNode

用多线程优化Excel表格数据导入校验的接口

公司的需求,当前某个Excel导入功能,流程是:读取Excel数据,传入后台校验每一条数据,判断是否符合导入要求,返回给前端,导入预览展示.(前端等待响应,难点).用户再点击导入按钮,进行异步导入(前端不等待,好做).当前接口仅支持300条数据,现在要求我要支持3000条数据. 解决问题,思路是关键. 首先,查看接口,找到读取表格的位置,看到判断,如果数据量大于300,直接返回.把300改成3000. 然后,分析导入数据校验,都是和哪些数据进行校验的,这些数据都是从数据库来的.每一次都从数据库查

Struts2数据的校验

通常,数据校验在客户端使用javascript来进行的,在这里做的是怎么在服务端使用XML配置文件来校验数据. 1,配置web.xml文件 <?xml version="1.0" encoding="UTF-8"?><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org