特性在框架中使用说明

一个实战参考案例

思路:

1.封装同一类型的特性

2.每种情况封装特性

3.标注特性

4.手动调用

1.封装同一类型的特性

项目过程中,难免会用到数据检证,用特性的方式处理检证问题;抽象特性,抽象方法VirifiProperty,参数是属性的值,通过这个方法验证属性数据是否合格;

 /// <summary>
    /// 封装抽象父类,抽象字段验证函数
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]//标记特性能标记的范围(当前只能标记属性和字段)
    public abstract class BasicAttribute : Attribute
    {
        protected string[] _ParaList;//接收测参数
        /// <summary>
        /// 构造函数接收参数
        /// </summary>
        /// <param name="para"></param>
        public BasicAttribute(params string[] para)
        {
            _ParaList = para;
        }

        /// <summary>
        /// 抽象字段验证方法
        /// </summary>
        /// <returns></returns>
        public abstract void VirifiProperty(object value);

    }

2.每种情况封装特性

对属性的长度,是否为空,是否为数值等,都封装成特性,这里是一个扩展点,可以根据不同的情况扩展多个特性,只要每个特性继承基类BasicAttribute

验证不合格可以有多种方式,当前项目用的是抛出自定义异常ExceptionAttribute,ExceptionAttribute是对Exception的封装,一是可以写一下特殊逻辑,一个是框架捕捉到异常后,可以区分出是特性抛出的异常以做单纯处理

 /// <summary>
    /// 字符串长度检验
    /// </summary>
    public class VirificationLenAttribute : BasicAttribute
    {
        /// <summary>
        /// 构造函数,2个参数,第一个是长度,第二个是字段中文名称
        /// </summary>
        /// <param name="para"></param>
        public VirificationLenAttribute(params string[] para) : base(para) { }
        /// <summary>
        /// 验证字段长度
        /// </summary>
        /// <param name="value">当前字段内容</param>
        /// <returns></returns>
        public override void VirifiProperty(object value)
        {
            if (value != null && value.ToString().Length > int.Parse(_ParaList[0]) && int.Parse(_ParaList[0]) != -1)
            {
               throw new ExceptionAttribute( $"列[{_ParaList[1]}]的长度超出范围,长度范围是{_ParaList[0]}");
            }
        }
    }
    /// <summary>
    /// 字符串不允许为空
    /// </summary>
    public class VirificationNotNullAttribute : BasicAttribute
    {
        /// <summary>
        /// 构造函数,1个参数,第一是字段中文名称
        /// </summary>
        /// <param name="para"></param>
        public VirificationNotNullAttribute(params string[] para) : base(para) { }
        /// <summary>
        /// 验证是否为空
        /// </summary>
        /// <param name="value">当前字段内容</param>
        /// <returns></returns>
        public override void VirifiProperty(object value)
        {
            if (value == null || string.IsNullOrEmpty(value.ToString()))
            {
                throw new ExceptionAttribute($"列不允许为空");
            }
        }
    }
    /// <summary>
    /// 整数值验证
    /// </summary>
    public class VirificationIntAttribute : BasicAttribute
    {
        /// <summary>
        /// 构造函数,1个参数,字段中文名称
        /// </summary>
        /// <param name="para"></param>
        public VirificationIntAttribute(params string[] para) : base(para) { }
        /// <summary>
        /// 判断是否是数值
        /// </summary>
        /// <param name="value">当前字段内容</param>
        /// <returns></returns>
        public override void VirifiProperty(object value)
        {
            try
            {
                //空的场合
                if (value == null || string.IsNullOrEmpty(value.ToString()))
                {
                    throw new ExceptionAttribute($"{_ParaList[0]}不能为空,请输入数值!");
                }
                int.Parse(value.ToString());
            }
            catch (Exception)
            {
                throw new ExceptionAttribute($"列[{_ParaList[0]}]是数值类型,请输入数值!");
            }

        }
    }
 public class ExceptionAttribute : Exception
    {
        public string msg { get; set; }
        /// <summary>
        ///封装exception,后期框架中,可以区分是特性异常
        /// </summary>
        /// <param name="message">异常消息</param>
        public ExceptionAttribute(string message)
            : base(message)
        {
            msg = message;
        }


    }

3.标注特性

在属性上面可以标记多个特性

public class ModelDemo
    {
        [VirificationInt("序号")]
        public int? id { get; set; }
        [VirificationLen("4", "姓名")]
        public string name { get; set; }
        [VirificationNotNull]
        [VirificationInt("序号")]
        public int? age { get; set; }

        public string remark { get; set; }

    }

用扩展的方式,操作特性

 /// <summary>
        /// 类检证
        /// </summary>
        /// <param name="obj"></param>
        public static void CheckModel( this object obj) {
            //获取类所有属性
            foreach (PropertyInfo item in obj.GetType().GetProperties())
            {
                //判断是否含有特性
                if (item.IsDefined(typeof(BasicAttribute),true))
                {
                    //找到当前类所有特性
                    var attributes = item.GetCustomAttributes(typeof(BasicAttribute), true);
                    foreach (var attribute in attributes)
                    {
                        //执行检证函数
                        BasicAttribute basicAttribute = (BasicAttribute)attribute;
                        basicAttribute.VirifiProperty(item.GetValue(obj));
                    }
                }
            }
        }

4.手动调用

本次是用抛出异常的方式处理特殊不合格的情况,实际方式有很多,如果框架没有对异常单独处理,可以改成返回值的方式.

 try
            {
                ModelDemo modelDemo = new ModelDemo();
                modelDemo.id = 10;
                modelDemo.name = "123";
                modelDemo.age = null;
                modelDemo.CheckModel();
            }
            catch (ExceptionAttribute ex)
            {
                //一般情况下,框架是用AOP的方式捕捉异常,集中处理
                //为了方便用这种方式替代
                Console.WriteLine(ex.msg);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值