zoukankan      html  css  js  c++  java
  • C#模型验证类的实现

     首先看一段代码

      public class TestController : BaseController
        {
    
    
            public ActionResult Create(Product product)
            {
                if (string.IsNullOrWhiteSpace(product.Name))  //判断商品名称是否为空
                {
                    return Content("商品Name不可为空");
                }
                if (string.IsNullOrWhiteSpace(product.CategoryId)) //判断商品类别Id是否为空
                {
                    return Content("商品CategoryId不可为空");
                }
                if (Service.BaseService.Query<Entity.Category>($"select *from dbo.[Category] where Id='{product.CategoryId}'").FirstOrDefault() == null) //判断商品类别Id是否为空
                {
                    return Content("不存在的商品CategoryId");
                }
    
    
                //todo 判断完成,写入数据库
    
    
    
                return Content("添加成功");
            }

                在做后端验证时,我们经常会写到如上的代码,判断是否为空,判断是否符合格式,判断是否存在于数据库中,写多了难免使人烦躁。

      好在Net框架中出现了数据标注System.ComponentModel.DataAnnotations。   这是一个很棒的组件,但是用起来并不顺手,比如他不能验证单个值,支持的属性也比较少,实际使用中很多需要自己来实现。

    所以接下来我们从头实现一个C#验证的插件,

    实现中。。。。。

    实现中。。。。。

    实现中。。。。。

    实现完成。

    基本配置

    首先定义一个验证类让所有需要的验证继承于此

        public abstract class ValidationAttribute : Attribute
        {
            public string ErrorMessage { get; set; }
            public string Name { get; set; }
            public virtual bool Verify(object o)
            {
                return false;
            }
        }
     1 using Common.EntityValidation;
     2 using System;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Web;
     6 
     7 namespace TestMvc.Models
     8 {
     9     public class Student
    10     {
    11 
    12         [NotNull(ErrorMessage = "Id是必须的")]    //验证非空,自定义ErroMessage
    13         public string Id { get; set; }
    14 
    15 
    16         [LengthAttribute(Max = 10, ErrorMessage = "个人介绍的长度")] //字符长度限制
    17         public string Introduce { get; set; }  //个人介绍
    18 
    19 
    20         [Range(Min =1,Max =120)]      //数值类型大小区间限制,最小,最大
    21         public int Age { get; set; }
    22 
    23 
    24         [Range( Min = "1900-10-10",Max = "2100-10-10")]   //字符类型的区间
    25         public string Birthday { get; set;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
    26 
    27 
    28         [Chinese]
    29         public string Name { get; set; }  //只能是中文
    30 
    31 
    32 
    33         [In(Range = "高中生,初中生,小学生")]
    34         public string StudentType { get; set; }//只能是  "高中生","初中生","小学生" 之一
    35 
    36 
    37       
    38 
    39 
    40 
    41         [DbValidation(Sql = "select*from dbo.[data] where id=@ClassId")]  //数据库验证,验证班级Id  ClassId是否存在于数据库中
    42         public string ClassId { get; set; }
    43 
    44 
    45 
    46         [Mobile]
    47         public string CellPhone { get; set; }
    48 
    49 
    50         [Email]
    51 
    52         public string Email { get; set; }
    53 
    54         [IdCard]
    55         public string IdCard { get; set; }
    56 
    57 
    58 
    59         [InEnum(RangeType = typeof(StuState))]  //只能是属于枚举中的值 ,0 或者 2或者4
    60         public int StuState { get; set; }
    61     }
    62 
    63     public enum StuState
    64     {
    65 
    66         上学中 = 0,
    67         肄业 = 2,
    68         退学 = 4,
    69 
    70 
    71     }
    72 }

     调用过程

    using Common.EntityValidation;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using TestMvc.Models;
    
    namespace TestMvc.Controllers
    {
        public class HomeController : Controller
        {
           
    
            public ActionResult Create(Student student)
            {
    
                #region
                var defaulVali = EntifyValidator.Validate(student);// 验证实体,默认验证所有字段
                #endregion
    
    
    
                #region
                var  IgnoreVali = EntifyValidator.Validate(student,"ClassId");// 验证实体,跳过字段ClassId的验证
                #endregion
    
    
                #region
                var r2 = EntifyValidator.ValidateQuickly(student);//快速验证,当有不通过的字段时,立即返回
    
                #endregion
                #region
    
                string pwd = Request["Pwd"];   
    
                var vPwd = StrongPassWordAttribute.IsValid(pwd); //验证单个value,验证是否强密码
    
                if (!vPwd.IsValid) 
                {
    
                    return Content(vPwd.ErrorMessage);   //这不是一个强密码
                }
    
                #endregion
    
    
                if (defaulVali.IsValid)   //返回true或者false
                {
    
                    return Content(defaulVali.ErrorMessage);
                }
                //TODO
                return Content("");
            }
    
    
        }
    
    
        //自定义
        public class CustomAttribute:ValidationAttribute
        {
    
    
            public override bool Verify(object o)
            {
                //这里写验证逻辑
    
    
                return false;
            }
    
        }
    }

    使用数据库验证时可以在应用程序入口初始化连接值

     

       

         protected void Application_Start()
    
            {
    
                AreaRegistration.RegisterAllAreas();
    
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    
                RouteConfig.RegisterRoutes(RouteTable.Routes);
    
                BundleConfig.RegisterBundles(BundleTable.Bundles);
    
     
    
                DbValidationAttribute.Init("server=XXXX;database=XX;user=sa;password=1234; pooling=true;max pool size=2048;");
    
     

    自定义

        //自定义
        public class CustomAttribute:ValidationAttribute
        {
    
    
            public override bool Verify(object o)
            {
                //这里写验证逻辑
    
    
                return false;
            }
    
        }

    验证的主要方法

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Common.EntityValidation
    {
        public class EntifyValidator
        {
            public static ValidResult Validate(object data, params string[] ignore) //验证完所有字段
            {
                return new EntifyValidator().Verify(false, data, ignore);
               
            }
            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));//
    
                    var input = item.GetValue(data);
    
                    foreach (var itemattr in validateattrs)
                    {
                        var attr = ((ValidationAttribute)itemattr);
                        if (attr != null)
                        {
                            attr.Name = item.Name;
                            var isvalid = attr.Verify(input);
    
                            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;
            }
        }
    }

     源码地址:https://gitee.com/unclescar/Validator

    欢迎下载,讨论,联系作者 QQ 634892969

  • 相关阅读:
    树形数据深度排序处理示例(递归法).sql
    12种JavaScript MVC框架之比较
    逐级汇总示例(用户定义函数法).sql
    名次查询的处理示例.sql
    实现删除指定结点及所有子节点的处理触发器.sql
    memcpy和memmove的区别
    据说是月薪2W的笔试题
    C++重点知识
    Java初学者需掌握的30个概念
    (转)微软面试题
  • 原文地址:https://www.cnblogs.com/jimsfriend/p/10238451.html
Copyright © 2011-2022 走看看