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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章