• MVC验证(自动在基类中验证实体的数据有效性),本人最满意的作品之一


    说起数据验证,在我的博客中文章不少,有MVC标准验证,有自己架构中用到的验证,但一个共同的问题就是重复的代码量太大,而且破坏了数据库实体本身的层次感!即数据(实体)有效性验证就应该在实体层去实现,不应该推迟到WEB层去做这事,在之前的文章中我介绍了使用统一实体基类来做这事,但需要每个实体都去干预自己的部分(可能大部分情况下,每个实体的某些验证都是相同的,如非空验证),这样,对于懒惰的程序员来说,是件很不爽的事,于是乎,开始想去解决这个问题了。

    原来的代码:  

    public virtual bool IsValid { get { return (this.GetRuleViolations().Count() == 0); } }
    public abstract IEnumerable<RuleViolation> GetRuleViolations();
    
    

    在派生类中去实现这个GetRuleViolations()方法:

    public override IEnumerable<RuleViolation> GetRuleViolations()
         {
    
               if (this.ConfirmPassword != this.Password && this.ConfirmPassword != this.NewPassword)
                 yield return new RuleViolation("两?次?密ü码?必?须?相à同?", "ConfirmPassword");
         }
    
    

    像上面的代码其实只是作了非空性验证,正常情况下,我们需要为每个非空的字段(属性)去做这样的验证,太悲哀了,于是,想到了下面的解决方法,将非空验证提取到基类中去做这事。

      #region 实体验证
    
        public virtual bool IsValid { get { return (this.GetRuleViolations().Count() == 0); } }
           public virtual IEnumerable<RuleViolation> GetRuleViolations()
            {
    
               PropertyInfo[] propertyInfo = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (var i in propertyInfo)
                {
                    if (i.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false) != null
                        && i.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false).Count() > 0
                        && !((System.Data.Linq.Mapping.ColumnAttribute)i.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false)[0]).CanBeNull
                        && !((System.Data.Linq.Mapping.ColumnAttribute)i.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false)[0]).IsPrimaryKey)
                        if (i.GetValue(this, null) == null || string.IsNullOrEmpty(i.GetValue(this, null).ToString()))
                            yield return new RuleViolation("*", i.Name);
                }
            }
             #endregion

    我们可以看到,基类中的GetRuleViolations() 已经被改造成了虚方法,即它要去做一些派生类共用的工作,本例是“非空验证”,而如果有个性化的验证,还是需要在指定的实体中去实现,代码可能是这样:

    public override IEnumerable<RuleViolation> GetRuleViolations()
           {
               #region 得到基类的非空验证迭代结果
    
              foreach (var violation in base.GetRuleViolations())
                   yield return violation;
               #endregion
               if (this.ConfirmPassword != this.Password && this.ConfirmPassword != this.NewPassword)
                   yield return new RuleViolation("两?次?密ü码?必?须?相à同?", "ConfirmPassword");
           }

    恩,这样的设计我才算是满意,一句话,共用的放在基类的虚方法,个性化的需要在实体类中复写基类方法,通过override关键字可以复写基类的抽象或方法,而不会覆盖掉它们,再配合base关键字,就可以调用基类的方法了,呵呵。

  • 相关阅读:
    浅入浅出数据结构(17)——有关排序算法的分析
    浅入浅出数据结构(16)——插入排序
    浅入浅出数据结构(15)——优先队列(堆)
    浅入浅出数据结构(14)——散列表
    浅入浅出数据结构(13)——平衡二叉查找树之AVL树
    浅入浅出数据结构(12)——从二分查找到二叉树
    老项目的#iPhone6与iPhone6Plus适配#Icon适配
    老项目的#iPhone6与iPhone6Plus适配#iOS8无法开启定位问题和#解决方案#
    老项目的#iPhone6于iPhone6Plus适配#iPhone6分辨率与适配
    iOS设备屏幕像素总览
  • 原文地址:https://www.cnblogs.com/lori/p/2445049.html
Copyright © 2020-2023  润新知