zoukankan      html  css  js  c++  java
  • 用特性来实现数据的校验

    在网站开发中,往往需要对用户输入的数据进行校验。
    而为了保持数据的完整性,我们需要进行客户端和服务端的双重校验。
    客户端的校验一般由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 "验证成功!";
    }

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

    总结

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

    项目地址

    https://github.com/NemoChris/AttributeValidate/tree/v0.1/AttributeValidate


    链接

    特性验证完结版

  • 相关阅读:
    JavaScript的执行
    关于k阶裴波那契序列的两种解法
    科普 eclipse中的Java build
    [BZOJ 1037] 生日聚会Party
    [POJ 1185] 炮兵阵地
    [POJ 1935] Journey
    [POJ 2397] Spiderman
    [POJ 2373][BZOJ 1986] Dividing the Path
    [POJ 3378] Crazy Thairs
    [POJ 2329] Nearest number-2
  • 原文地址:https://www.cnblogs.com/simple-blog/p/4915811.html
Copyright © 2011-2022 走看看