• c# 特性之模型验证数据和设置默认值


    封装验证特性

    public abstract class ValidationAttribute : Attribute
        {
            public ValidationAttribute()
            {
                ErrorMessage = "";
                Name = "";
            }
    
            /// <summary>
            /// 错误消息
            /// </summary>
            public string ErrorMessage { get; set; }
            /// <summary>
            /// 字段名称
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// 验证过程
            /// </summary>
            /// <param name="o"></param>
            /// <returns></returns>
            public virtual bool Verify(object o)
            {
                return false;
            }
    
            /// <summary>
            /// 默认值
            /// </summary>
            public object DefaultValue { get; set; }
        }

    错误信息实体

    public class ValidResult
        {
    
            public ValidResult()
            {
                ValidResultDetails = new List<ValidResultDetail>();
    
            }
    
            public bool IsValid
            {
                get
                {
    
                    return ValidResultDetails.Count() == 0;
                }
            }
            public virtual string ErrorMessage
            {
                get
                {
                    string r = null;
    
                    if (ValidResultDetails.Count() > 0)
                    {
    
                        r = ValidResultDetails.FirstOrDefault().ErrorMessage;
                    }
    
                    return r;
                }
                set
                {
                    value = ErrorMessage;
    
    
                }
            }  //错误摘要
            public List<ValidResultDetail> ValidResultDetails { get; set; }
        }
        public class ValidResultDetail
        {
            public string Name { get; set; }
            public bool IsValid
            {
                get; set;
            }
            public virtual string ErrorMessage { get; set; }
        }

    验证类

    public class EntifyValidator
        {
            /// <summary>
            /// 验证完所有字段
            /// </summary>
            public static ValidResult Validate(object data, params string[] ignore)
            {
                return new EntifyValidator().Verify(false, data, ignore);
            }
    
            /// <summary>
            ///  当有未通过的验证时,直接返回,停止验证
            /// </summary>
            public static ValidResult ValidateQuickly(object data, params string[] ignore)
            {
                return new EntifyValidator().Verify(true, data, ignore);
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="quickly">验证完所有字段Or验证到未通过的立即返回</param>
            /// <param name="data">需要验证的数据</param>
            /// <param name="ignore">忽略的字段</param>
            /// <returns></returns>
            public virtual ValidResult Verify(bool quickly, object data, params string[] ignore)
            {
                ValidResult result = new ValidResult();
                List<PropertyInfo> props = data.GetType().GetProperties().Where(a => !ignore.Contains(a.Name.ToLower())).ToList();
                foreach (var item in props)
                {
                    var validateattrs = item.GetCustomAttributes(typeof(ValidationAttribute), true);
                    var input = item.GetValue(data, null);
                    foreach (var itemattr in validateattrs)
                    {
                        var attr = ((ValidationAttribute)itemattr);
                        if (attr != null)
                        {
                            attr.Name = item.Name;
                            SetDefaultValue(data, item, attr);
                            var isvalid = attr.Verify(input);
                            if (string.IsNullOrEmpty(attr.ErrorMessage)) continue;
                            if (!isvalid)
                            {
                                ValidResultDetail validResultDetail = new ValidResultDetail();
                                validResultDetail.Name = item.Name;
                                validResultDetail.ErrorMessage = string.Format(attr.ErrorMessage, item.Name);
                                validResultDetail.IsValid = false;
                                result.ValidResultDetails.Add(validResultDetail);
                                if (quickly)
                                {
                                    return result;
                                }
                            }
                        }
                    }
                }
                return result;
            }
            /// <summary>
            /// 设置默认值
            /// </summary>
            private void SetDefaultValue(object data, PropertyInfo item, ValidationAttribute attr)
            {
                var input = item.GetValue(data, null);
                if (attr.DefaultValue != null && input == null)//设置默认值
                {
                    item.SetValue(data, attr.DefaultValue, null);
                }
                else if (attr.DefaultValue != null && input.GetType().Name == "DateTime")
                {
                    if (Convert.ToDateTime(input) == DateTime.MinValue)
                    {
                        item.SetValue(data, Convert.ToDateTime(attr.DefaultValue), null);
                    }
                }
            }
        }

    封装的简单验证特性

    public class InEnumAttribute : ValidationAttribute
        {
            public InEnumAttribute()
            {
                ErrorMessage = "{0}应该在区间内";
            }
    
            public Type RangeType { get; set; }
    
            public override bool Verify(object o)
            {
                if (o == null)
                {
                    return false;
                }
                var r = false;
                foreach (var item in Enum.GetValues(RangeType))
                {
                    if (((int)item) == Convert.ToInt32(o))
                    {
                        r = true;
                        break;
                    }
                }
                return r;
            }
        }
    public class NotNullAttribute : ValidationAttribute
        {
            public bool? NotNull { get; set; } = true;
            public NotNullAttribute()
            {
                ErrorMessage = "{0}必填";
            }
            public override bool Verify(object o)
            {
                if (o == null)
                {
                    return false;
                }
                else if (string.IsNullOrWhiteSpace(o.ToString()))
                {
                    return false;
                }
                return true;
            }
        }
    
        /// <summary>
        /// 默认值
        /// </summary>
        public class DValueAttribute : ValidationAttribute
        {
            public DValueAttribute()
            {
    
            }
        }

    使用方式在要验证的实体类型加特性

      /// <summary>
            /// 转单
            /// </summary>    
            [NotNull(ErrorMessage = "转单必填")]
            public string cserviceno { get; set; }
     /// <summary>
            /// 修改时间
            /// </summary>        
            [DValue(DefaultValue = "1900-01-01 00:00:00")]
            public DateTime dlastmod { get; set; }
    /// <summary>
            /// 包裹类型
            /// </summary>        
            [InEnum(ErrorMessage = "包裹类型错误", RangeType = typeof(Nitemtype))]
            public Nitemtype nitemtype { get; set; }

    调用

     var r = EntifyValidator.Validate(rec);
                    if (!r.IsValid)
                    {
                       r.ValidResultDetails.Select(item => item.ErrorMessage);
                    }
  • 相关阅读:
    C#中 栈,堆你真的懂吗?不理解引用类型和值类型区别的程序员将会给代码引入诡异的bug和性能问题
    c# 可空类型,语法糖,lambda,命名规则(Pascal 帕斯卡命名,Camel 驼峰命名),注释,封装,继承,多态
    数据库事务,游标,触发器,存储过程,索引,数字,日期转换为字符,字符串操作,查询,分类,内连接,外连接,全连接,模糊查询,范围查询,5种聚合函数,分组查询,主键,外键,标识列
    html,css 知识汇总
    html,css,js,jquery
    数据库文件托管
    final,finally,finalize的区别
    Thread,Threadpool,task的区别
    ABP 一个开源的web开发框架
    redis 40问
  • 原文地址:https://www.cnblogs.com/shuaimeng/p/14101504.html
Copyright © 2020-2023  润新知