zoukankan      html  css  js  c++  java
  • 通过反射验证对象属性值

    数据交互是WEB交互的核心功能,用户在Web页面的表单中提交数据,程序接受数据后进行相应的逻辑运算后将数据写入数据库中,在这样的应用中无论 是考虑到应用系统的安全还是用户数据的完整,我们都将对用户提交的数据信息进行相应的验证。

    比如一个用户注册的交互应用:

    一般会在Model层建立一个注册类

    public class Register
    {
    public string Account { get; set; }
    public string Password { get; set; }
    public string Email { get; set; }
    }

    在UI层将页面提交来的数据对应赋予Register类实例化后的对象的属性,之后将对象传递给BLL层进行数据库的操作

    代码
    Register register = new Register();
    register.Account
    = HttpContext.Current.Request["txtAccount"].Trim();
    register.Password
    = HttpContext.Current.Request["txtPassword"].Trim();
    register.Email
    = HttpContext.Current.Request["txtEmail"].Trim();

    在这里,我们暂不谈数据的安全性,只讨论数据的完整性,在这样的应用中Register类中的Account和Password属性,作为用户今后 登录的重要依据,是必填的,通常情况下,我们会在将参数赋值给对象属性前先进行判断是否为空的操作

    string account = string.Empty;
    if (!string.IsNullOrEmpty(HttpContext.Current.Request["txtAccount"]))
    {
    account
    = HttpContext.Current.Request["txtAccount"].Trim();
    }
    register.Account
    = account;

    但是,当一个需要赋值的对象的属性非常多时,我们的判断工作将是灾难性的。

    还好,.Net为我们提供了Attribute类(字面上解释应该叫做“属性”,但我叫它“修饰”,因为它和类的“Property”同名)

    我们可以通过建立一个验证用的Attribute对象VerifyAttribute,并给Register类的属性加上 VerifyAttribute型的修饰,记录下属性的规则,比如类型、是否可以为空,最大值以及最小值等,并建立一个通过对象属性修饰 (Attribute)验证对象属性规则的类Verify,在Register对象个属性赋值好后,通过Verify的验证过程,返回验证信息。

    代码
    /// <summary>
    /// 实体属性验证设置特性对象
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
    public abstract class VerifyAttribute : Attribute
    {
    /// <summary>
    /// 说明
    /// </summary>
    protected string _Explain;

    /// <summary>
    /// 是否可以为空
    /// </summary>
    protected bool _NotNull;

    /// <summary>
    /// 正则表达式
    /// </summary>
    protected string _RegexExpressions;

    /// <summary>
    /// 获取说明
    /// </summary>
    public string Explain
    {
    get { return _Explain; }
    }

    /// <summary>
    /// 获取是否可以为空值
    /// </summary>
    public bool NotNULL
    {
    get { return _NotNull; }
    }

    /// <summary>
    /// 获取验证正则表达式
    /// </summary>
    public string RegexExpressions
    {
    get { return _RegexExpressions; }
    }

    /// <summary>
    /// 为内部字段赋值
    /// </summary>
    /// <param name="explain">属性说明</param>
    /// <param name="notnull">是否不可为空</param>
    /// <param name="regexexpressions">正则表达式,为空不验证</param>
    protected void GetParam(string explain, bool notnull, string regexexpressions)
    {
    _Explain
    = explain;
    _NotNull
    = notnull;
    _RegexExpressions
    = regexexpressions;
    }
    }
    代码
    /// <summary>
    /// 实体字符类型属性验证设置特性对象
    /// </summary>
    public class VerifyString : VerifyAttribute
    {
    /// <summary>
    /// 最大长度
    /// </summary>
    protected int _MaxLength;

    /// <summary>
    /// 获取最大长度
    /// </summary>
    public int MaxLength
    {
    get { return _MaxLength; }
    }

    /// <summary>
    /// 为实体字符类型属性设置验证特性
    /// </summary>
    /// <param name="explain">属性说明</param>
    /// <param name="notnull">是否可以为空</param>
    /// <param name="maxlength">属性值最大长度</param>
    public VerifyString(string explain, bool notnull, int maxlength)
    {
    _MaxLength
    = maxlength;
    GetParam(explain, notnull,
    "");
    }

    /// <summary>
    /// 为实体字符类型属性设置验证特性
    /// </summary>
    /// <param name="explain">属性说明</param>
    /// <param name="notnull">是否可以为空</param>
    public VerifyString(string explain,bool notnull) {
    _MaxLength
    = 0;
    GetParam(explain, notnull,
    "");
    }

    /// <summary>
    /// 为实体字符类型属性设置验证特性
    /// </summary>
    /// <param name="explain">属性说明</param>
    /// <param name="notnull">是否可以为空</param>
    /// <param name="maxlength">属性值最大长度</param>
    /// <param name="regexexpressions">正则表达式,为空不验证</param>
    public VerifyString(string explain, bool notnull, int maxlength, string regexexpressions)
    {
    _MaxLength
    = maxlength;
    GetParam(explain, notnull, regexexpressions);
    }
    }

    上面两个类VerifyString继承自VerifyAttribute类,主要是用作对String类型的属性的修饰,其中加入了可通过正则表 达式进行验证的功能。

    建立实现验证过程的对象

    代码
    /// <summary>
    /// 实例属性数据格式验证对象
    /// </summary>
    public class Verify {

    /// <summary>
    /// 验证属性数据格式,并返回验证结果
    /// </summary>
    /// <typeparam name="T">必须继承自BaseObject</typeparam>
    /// <param name="t">要验证的实例</param>
    /// <param name="separator">分割验证结果的自定义分隔符</param>
    /// <returns>验证结果</returns>
    public static string VerificationDataToString<T>(T t, string separator)
    {
    System.Type type
    = t.GetType();
    StringBuilder strTmp
    = new StringBuilder();
    foreach (PropertyInfo P in type.GetProperties())
    {
    foreach (Attribute attr in P.GetCustomAttributes(true))
    {
    VerifyAttribute vattr
    = attr as VerifyAttribute;
    string typename = vattr.GetType().ToString();
    typename
    = typename.Substring(typename.LastIndexOf(".") + 1);
    object pv = P.GetValue(t, null);
    if (vattr.NotNULL)
    {
    if (pv == null || pv.ToString() == "")
    {
    strTmp.AppendFormat(
    "{0}不得为空{1}", vattr.Explain, separator);
    }
    }

    switch (typename)
    {
    case "VerifyString":
    VerifyString vattrs
    = (VerifyString) vattr;
    if (pv != null)
    {
    if (vattrs.MaxLength > 0)
    {
    if (pv.ToString().Length > vattrs.MaxLength)
    {
    strTmp.AppendFormat(
    "{0}长度不得超过{1},现在是{2}{3}",
    vattrs.Explain,
    vattrs.MaxLength,
    pv.ToString().Length,
    separator);
    }
    }
    }
    break;
    case "VerifyDate":

    break;
    case "VerifyNumber":

    break;
    }
    if(vattr.RegexExpressions != "")
    {
    if(pv != null)
    {
    if(!TestRegex(pv.ToString(), vattr.RegexExpressions))
    strTmp.AppendFormat(
    "{0}不符合格式要求{1}", vattr.Explain, separator);
    }
    }
    }
    }
    if (strTmp.ToString().Length <= 0) return "";
    else return strTmp.ToString().Substring(0, strTmp.ToString().LastIndexOf(separator));
    }

    /// <summary>
    /// 通过正则检查字符中是否存在指定字符
    /// </summary>
    /// <param name="value">要检查的字符串</param>
    /// <param name="regex">正则表达式</param>
    /// <returns>真or假</returns>
    private static bool TestRegex(string value, string regex)
    {
    return Regex.IsMatch(value, regex);
    }

    }

    函数VerificationData(),接受一个泛型对象,并遍历对象的属性以及属性的修饰(Attribute),取出属性的值后根据修饰描 述的规则进行验证判断,最后返回验证结果。

    这样,我们修改之前的Register类,为其属性加上VerifyAttribute验证规则修饰

    代码
    public class Register
    {
    //必填,长度不得超过50字符,启用正则验证规则"^[\w|@|.|_]{2,20}$"
    [VerifyString("账户", true, 50, RegularExpression.Account)]
    public string Account { get; set; }

    //必填,长度不得超过50字符,启用正则验证规则"^[a-zA-Z0-9]{6,20}$"
    [VerifyString("密码", true, 50, RegularExpression.Password)]
    public string Password { get; set; }

    //必填,长度不得超过150字符,启用正则验证规则"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"
    [VerifyString("邮箱", true, 150, RegularExpression.Email)]
    public string Email { get; set; }
    }

    在实际应用中我们通过Verify对象的VerificationData函数返回验证结果

    代码
    string account = "";
    string password = "$%123";
    string email = "ffssfs@fdfds";

    string err = string.Empty;

    Register register
    = new Register();
    register.Account
    = account;
    register.Password
    = password;
    register.Email
    = email;

    err
    = Verify.VerificationData<Register>(register,"<br/>");

    if(err == string.Empty)
    {
    //验证通过
    }
    else
    {
    HttpContext.Current.Response.Write(err);
    err应该返回:“账号不能为空
    <br/>请正确填写账号<br/>请正确填写密码<br/>请正确填写邮箱”
    }

    代码是从之前的项目中拷贝过来的,没有再次经过测试,如果有问题请与我联系,非常感谢!!

  • 相关阅读:
    快速排序
    推荐!手把手教你使用Git
    「瞻前顾后」写出我心(九十九)
    「减法」写出我心(九十八)
    「焦虑」写出我心(九十七)
    「认知水平」​​​​​​​​写出我心(九十六)
    「成功的事业」写出我心(九十五)
    「爱」​​​​​​写出我心(九十四)
    「赢」​​​​​写出我心(九十三)
    「体面人」​​​​写出我心(九十二)
  • 原文地址:https://www.cnblogs.com/goody9807/p/1707526.html
Copyright © 2011-2022 走看看