好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

巧用特性减少代码书写量。

巧用特性减少代码书写量。

您还在为每次添加数据或者修改数据的时候,书写大量的代码判断输入是否合法而发愁吗?

如果是,我这里可以为您提供一个好的解决方案。先看我列出的一个实体类例子:

?

using   System;

using   System.Collections.Generic;

using   System.Linq;

using   System.Text;

 

using   Attributes;

using   System.Data;

 

namespace   Model

{

     public   class   cms_article

     {

         [Model(Name = "ID" , Empty = false , DataType = DbType.Int32, ErrorTip = "ID不能为空,且必须为整数" , AutoIncrement = true , PrimaryKey = true )]

         public   int   ArticleID { get ; set ; }

         [Model(Name = "标题" , Empty = false , DataType = DbType.String, MinLength = 2, MaxLength = 5, ErrorTip = "请为标题输入2-5个字符,谢谢!" )]

         public   string   ArticleTitle { get ; set ; }

         [Model(Name = "内容" , Empty = false , DataType = DbType.String, Rule = @"^[\s\S]+$" , ErrorTip = "内容不能为空" )]

         public   string   ArticleContent { get ; set ; }

         [Model(Name = "发布日期" , Empty = true , DataType = DbType.DateTime)]

         public   DateTime ArticleDateTime { get ; set ; }

         [Model(Name = "所属类别" , Empty = false , DataType = DbType.Int32)]

         public   int   ClassID { get ; set ; }

     }

}

看到这,知道我在唱哪出戏了吧?您可能会想到:特性(attribute)。对,就是它。我们可以巧用特性来处理大量的输入判断。如果您感兴趣,继续往下看吧。

有人也许会说,没必要,我在客户端用JS判断就行了。大哥,省省吧。如果网站是面向互联网的,您仅仅用JS判断用户的输入,无疑是自掘坟墓。

******************************************************************************************

我们为什么要这么做?

试想,如果一个系统有几十个,甚至几百个表。您在进行添加或者修改的时候是不是要对用户的输入进行合法性的判断?那是不是意味着每个Add()或者Update()方法里面都要写很多判断代码??天呢,请原谅我,我没有这么多时间来浪费我的青春了。。。那我们应该怎么做呢?这就是我们要解决的问题,也是我写这篇文章的目的。

明白了我们要解决什么问题,下面的事情就好办了。

我们如何做:

需要说明的是:您必须具备C#反射的知识,不然您是看不下去的。

还有,假设数据库字段跟网页的form表单元素是对应的,如果您不喜欢这么做,建议您不要往下看下去了,因为我觉得这是在浪费您的时间。

好,开始。我们先在大脑里,模拟用户输入数据,然后提交,然后在这里我们就要绑定Model了。

我们可以这么做:

?

//绑定Model

Model.cms_article modelArticle = Lib.Model.Instance().BindModel<Model.cms_article>();

Model.cms_article是一个类型,比如:文章。BindModel是个静态方法。

然后看BindModel方法:

?

/// <summary>

/// 绑定Model

/// </summary>

/// <typeparam name="T"></typeparam>

/// <returns></returns>

public   T BindModel<T>() where T : new ()

{

     T entity = new   T();

     PropertyInfo[] Properties = typeof (T).GetProperties(); //获取当前类型的所有属性

     //遍历属性集合

     foreach   (PropertyInfo Property in   Properties)

     {

         //获取属性的值

         string   value = System.Web.HttpContext.Current.Request[Property.Name];

         //获取当前属性所指定的特性

         object [] attributes = Property.GetCustomAttributes( typeof (Attributes.ModelAttribute), false );

         if   (attributes.Length > 0)

         {

             this .modelCheck.CheckInput(attributes[0] as   Attributes.ModelAttribute, value);

         }

         //给实体赋值

         if   (value != null )

         {

             Property.SetValue(entity, Convert.ChangeType(value, (System.Nullable.GetUnderlyingType(Property.PropertyType) ?? Property.PropertyType)), null );

         }

     }

     return   entity;

}

先是根据反射获取Model的所有属性,遍历循环

然后根据属性获取其所拥有的特性,如果当前属性找到有特性存在,我们则遍历所有特性。

在这里我不需要查找所有的特性,因为我知道我需要什么特性,所以我就取第一个特性attributes[0] as ModelAttribute。

再然后根据当前属性所拥有的特性,对输入的数据进行判断。this.modelCheck.CheckInput(attributes[0] as Attributes.ModelAttribute, value);

         ///   <summary> 
         ///   检测输入数据的合法性,统一在这里处理
          ///   </summary> 
         ///   <param name="modelAttribute"></param> 
         ///   <param name="value"></param> 
         ///   <returns></returns> 
         public   string  CheckInput(Attributes.ModelAttribute modelAttribute,  string   value)
        {
              string  str =  string  .Empty;
              //  判断是否允许为空,如果不允许为空 
             if  (! modelAttribute.Empty)
            {
                  this  .CheckEmpty(modelAttribute, value);
                  this  .CheckType(modelAttribute, value);
                  this  .CheckLength(modelAttribute, value);
                  this  .CheckRule(modelAttribute, value);
            }
              else  
            {
                  if  (! string  .IsNullOrEmpty(value))
                {
                      this  .CheckType(modelAttribute, value);
                      this  .CheckLength(modelAttribute, value);
                      this  .CheckRule(modelAttribute, value);
                }
            }
              return   str;
        } 

最后是利用我们所约定的规则进行判断。

         ///   <summary> 
         ///   检测正则表达式
          ///   </summary> 
         ///   <param name="modelAttribute"></param> 
         ///   <param name="value"></param> 
         private   void  CheckRule(Attributes.ModelAttribute modelAttribute,  string   value)
        {
              if  (! string  .IsNullOrEmpty(modelAttribute.Rule))
            {
                  if  (! Common.RegexMatch(value, modelAttribute.Rule))
                {
                    Javascript.Alert(modelAttribute.ErrorTip,   true  );
                }
            }
        }
          ///   <summary> 
         ///   检测长度
          ///   </summary> 
         ///   <param name="modelAttribute"></param> 
         ///   <param name="value"></param> 
         private   void  CheckLength(Attributes.ModelAttribute modelAttribute,  string   value)
        {
              if  (modelAttribute.MinLength >  0  || modelAttribute.MaxLength >  0  )
            {
                  if  (value.Length < modelAttribute.MinLength || value.Length >  modelAttribute.MaxLength)
                {
                    Javascript.Alert(modelAttribute.ErrorTip,   true  );
                }
            }
        }
          ///   <summary> 
         ///   检测是否为空
          ///   </summary> 
         ///   <param name="modelAttribute"></param> 
         ///   <param name="value"></param> 
         private   void  CheckEmpty(Attributes.ModelAttribute modelAttribute,  string   value)
        {
              if  ( string  .IsNullOrEmpty(value))
            {
                Javascript.Alert(modelAttribute.ErrorTip,   true  );
            }
        }
          ///   <summary> 
         ///   判断数据类型
          ///   </summary> 
         ///   <param name="modelAttribute"></param> 
         ///   <param name="value"></param> 
         private   void  CheckType(Attributes.ModelAttribute modelAttribute,  string   value)
        {
              switch   (modelAttribute.DataType)
            {
                  case   DbType.AnsiString:
                      break  ;
                  case   DbType.AnsiStringFixedLength:
                      break  ;
                  case   DbType.Binary:
                      break  ;
                  case   DbType.Boolean:
                      if  (! Common.IsBool(value))
                    {
                        Javascript.Alert(modelAttribute.Name  +  "  字段类型不对,谢谢!  " ,  true  );
                    }
                      break  ;
                  case   DbType.Byte:
                      break  ;
                  case   DbType.Currency:
                      break  ;
                  case   DbType.Date:
                      break  ;
                  case   DbType.DateTime:
                      if  (! Common.IsDateTime(value))
                    {
                        Javascript.Alert(modelAttribute.Name  +  "  字段类型不对,谢谢!  " ,  true  );
                    }
                      break  ;
                  case   DbType.DateTime2:
                      break  ;
                  case   DbType.DateTimeOffset:
                      break  ;
                  case   DbType.Decimal:
                      if  (! Common.IsDecimal(value))
                    {
                        Javascript.Alert(modelAttribute.Name  +  "  字段类型不对,谢谢!  " ,  true  );
                    }
                      break  ;
                  case   DbType.Double:
                      if  (! Common.IsDouble(value))
                    {
                        Javascript.Alert(modelAttribute.Name  +  "  字段类型不对,谢谢!  " ,  true  );
                    }
                      break  ;
                  case   DbType.Guid:
                      break  ;
                  case   DbType.Int16:
                      if  (! Common.IsInt16(value))
                    {
                        Javascript.Alert(modelAttribute.Name  +  "  字段类型不对,谢谢!  " ,  true  );
                    }
                      break  ;
                  case   DbType.Int32:
                      if  (! Common.IsInt32(value))
                    {
                        Javascript.Alert(modelAttribute.Name  +  "  字段类型不对,谢谢!  " ,  true  );
                    }
                      break  ;
                  case   DbType.Int64:
                      if  (! Common.IsInt64(value))
                    {
                        Javascript.Alert(modelAttribute.Name  +  "  字段类型不对,谢谢!  " ,  true  );
                    }
                      break  ;
                  case   DbType.Object:
                      break  ;
                  case   DbType.SByte:
                      break  ;
                  case   DbType.Single:
                      break  ;
                  case   DbType.String:
                      break  ;
                  case   DbType.StringFixedLength:
                      break  ;
                  case   DbType.Time:
                      break  ;
                  case   DbType.UInt16:
                      break  ;
                  case   DbType.UInt32:
                      break  ;
                  case   DbType.UInt64:
                      break  ;
                  case   DbType.VarNumeric:
                      break  ;
                  case   DbType.Xml:
                      break  ;
                  default  :
                      break  ;
            }
        } 

思路很清晰吧?上面的这个方法就是我们的约定,因为有人说过:约定胜于配置。我觉得这几个方法足可以应付日常的开发了。您觉得呢?

 

 

 

标签:  反射 ,  特性 ,  绑定Model

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于巧用特性减少代码书写量。的详细内容...

  阅读:38次