91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在.NET中利用Attribute對數據進行校驗

發布時間:2021-01-28 09:40:57 來源:億速云 閱讀:196 作者:Leah 欄目:開發技術

如何在.NET中利用Attribute對數據進行校驗?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

前言

Attribute(特性)的概念不在此贅述了,相信有點.NET基礎的開發人員都明白,用過Attribute的人也不在少數,畢竟很多框架都提供自定義的屬性,類似于Newtonsoft.JSON中JsonProperty、JsonIgnore等

自定義特性

.NET 框架允許創建自定義特性,用于存儲聲明性的信息,且可在運行時被檢索。該信息根據設計標準和應用程序需要,可與任何目標元素相關。

創建并使用自定義特性包含四個步驟:

  • 聲明自定義特性

  • 構建自定義特性

  • 在目標程序元素上應用自定義特性

  • 通過反射訪問特性

聲明自定義特性

一個新的自定義特性必須派生自System.Attribute類,例如:

public class FieldDescriptionAttribute : Attribute
{
  public string Description { get; private set; }

  public FieldDescriptionAttribute(string description)
  {
    Description = description;
  }
}
public class UserEntity
{
  [FieldDescription("用戶名稱")]
  public string Name { get; set; }
}

該如何拿到我們標注的信息呢?這時候需要使用反射獲取

   var type = typeof(UserEntity);
   var properties = type.GetProperties();
   foreach (var item in properties)
   {
     if(item.IsDefined(typeof(FieldDescriptionAttribute), true))
     {
       var attribute = item.GetCustomAttribute(typeof(FieldDescriptionAttribute)) as FieldDescriptionAttribute;
       Console.WriteLine(attribute.Description);
     }
   }

執行結果如下:

如何在.NET中利用Attribute對數據進行校驗

從執行結果上看,我們拿到了我們想要的數據,那么這個特性在實際使用過程中,到底有什么用途呢?

Attribute特性妙用

在實際開發過程中,我們的系統總會提供各種各樣的對外接口,其中參數的校驗是必不可少的一個環節。然而沒有特性時,校驗的代碼是這樣的:

 public class UserEntity
 {
   /// <summary>
   /// 姓名
   /// </summary>
   [FieldDescription("用戶名稱")]
   public string Name { get; set; }

   /// <summary>
   /// 年齡
   /// </summary>
   public int Age { get; set; }

   /// <summary>
   /// 地址
   /// </summary>
   public string Address { get; set; }
 }
   UserEntity user = new UserEntity();

   if (string.IsNullOrWhiteSpace(user.Name))
   {
     throw new Exception("姓名不能為空");
   }
   if (user.Age <= 0)
   {
     throw new Exception("年齡不合法");
   }
   if (string.IsNullOrWhiteSpace(user.Address))
   {
     throw new Exception("地址不能為空");
   }

字段多了之后這種代碼就看著非常繁瑣,并且看上去不直觀。對于這種繁瑣又惡心的代碼,有什么方法可以優化呢?
使用特性后的驗證寫法如下:

首先定義一個基礎的校驗屬性,提供基礎的校驗方法

  public abstract class AbstractCustomAttribute : Attribute
  {
    /// <summary>
    /// 校驗后的錯誤信息
    /// </summary>
    public string ErrorMessage { get; set; }

    /// <summary>
    /// 數據校驗
    /// </summary>
    /// <param name="value"></param>
    public abstract void Validate(object value);
  }

然后可以定義常用的一些對應的校驗Attribute,例如RequiredAttribute、StringLengthAttribute

/// <summary>
    /// 非空校驗
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class RequiredAttribute : AbstractCustomAttribute
    {
      public override void Validate(object value)
      {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
        {
          throw new Exception(string.IsNullOrWhiteSpace(ErrorMessage) ? "字段不能為空" : ErrorMessage);
        }
      }
    }

    /// <summary>
    /// 自定義驗證,驗證字符長度
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class StringLengthAttribute : AbstractCustomAttribute
    {
      private int _maxLength;
      private int _minLength;

      public StringLengthAttribute(int minLength, int maxLength)
      {
        this._maxLength = maxLength;
        this._minLength = minLength;
      }

      public override void Validate(object value)
      {
        if (value != null && value.ToString().Length >= _minLength && value.ToString().Length <= _maxLength)
        {
          return;
        }

        throw new Exception(string.IsNullOrWhiteSpace(ErrorMessage) ? $"字段長度必須在{_minLength}與{_maxLength}之間" : ErrorMessage);
      }
    }

添加一個用于校驗的ValidateExtensions

public static class ValidateExtensions
 {
   /// <summary>
   /// 校驗
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <returns></returns>
   public static void Validate<T>(this T entity) where T : class
   {
     Type type = entity.GetType();

     foreach (var item in type.GetProperties())
     {
       //需要對Property的字段類型做區分處理針對Object List 數組需要做區分處理
       if (item.PropertyType.IsPrimitive || item.PropertyType.IsEnum || item.PropertyType.IsValueType || item.PropertyType == typeof(string))
       {
         //如果是基元類型、枚舉類型、值類型或者字符串 直接進行校驗
         CheckProperty(entity, item);
       }
       else
       {
         //如果是引用類型
         var value = item.GetValue(entity, null);
         CheckProperty(entity, item);
         if (value != null)
         {
           if ((item.PropertyType.IsGenericType && Array.Exists(item.PropertyType.GetInterfaces(), t => t.GetGenericTypeDefinition() == typeof(IList<>))) || item.PropertyType.IsArray)
           {
             //判斷IEnumerable
             var enumeratorMI = item.PropertyType.GetMethod("GetEnumerator");
             var enumerator = enumeratorMI.Invoke(value, null);
             var moveNextMI = enumerator.GetType().GetMethod("MoveNext");
             var currentMI = enumerator.GetType().GetProperty("Current");
             int index = 0;
             while (Convert.ToBoolean(moveNextMI.Invoke(enumerator, null)))
             {
               var currentElement = currentMI.GetValue(enumerator, null);
               if (currentElement != null)
               {
                 currentElement.Validate();
               }
               index++;
             }
           }
           else
           {
             value.Validate();
           }
         }
       }
     }
   }

   private static void CheckProperty(object entity, PropertyInfo property)
   {
     if (property.IsDefined(typeof(AbstractCustomAttribute), true))//此處是重點
     {
       //此處是重點
       foreach (AbstractCustomAttribute attribute in property.GetCustomAttributes(typeof(AbstractCustomAttribute), true))
       {
         if (attribute == null)
         {
           throw new Exception("AbstractCustomAttribute not instantiate");
         }

         attribute.Validate(property.GetValue(entity, null));
       }
     }
   }
 }

新的實體類

 public class UserEntity
 {
   /// <summary>
   /// 姓名
   /// </summary>
   [Required]
   public string Name { get; set; }

   /// <summary>
   /// 年齡
   /// </summary>
   public int Age { get; set; }

   /// <summary>
   /// 地址
   /// </summary>
   [Required]
   public string Address { get; set; }

   [StringLength(11, 11)]
   public string PhoneNum { get; set; }
 }

調用方式

UserEntity user = new UserEntity();
user.Validate();

關于如何在.NET中利用Attribute對數據進行校驗問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

棋牌| 柳江县| 安宁市| 邛崃市| 独山县| 若尔盖县| 荆州市| 沁水县| 陇川县| 广昌县| 滦南县| 来宾市| 棋牌| 辽中县| 腾冲县| 沛县| 广昌县| 神木县| 咸阳市| 鸡泽县| 定陶县| 高州市| 遂溪县| 枞阳县| 开原市| 乡宁县| 定日县| 桂林市| 交城县| 尼玛县| 永福县| 偏关县| 泽库县| 桂东县| 邯郸县| 上思县| 股票| 阳谷县| 阿瓦提县| 彭山县| 桃园县|