最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于.NET Attribute在數(shù)據(jù)校驗(yàn)中的應(yīng)用教程

 更新時(shí)間:2020年05月13日 08:45:27   作者:hexuwsbg  
這篇文章主要給大家介紹了關(guān)于.NET Attribute在數(shù)據(jù)校驗(yàn)中的應(yīng)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用.NET具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

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

自定義特性

.NET 框架允許創(chuàng)建自定義特性,用于存儲(chǔ)聲明性的信息,且可在運(yùn)行時(shí)被檢索。該信息根據(jù)設(shè)計(jì)標(biāo)準(zhǔn)和應(yīng)用程序需要,可與任何目標(biāo)元素相關(guān)。

創(chuàng)建并使用自定義特性包含四個(gè)步驟:

  • 聲明自定義特性
  • 構(gòu)建自定義特性
  • 在目標(biāo)程序元素上應(yīng)用自定義特性
  • 通過反射訪問特性

聲明自定義特性

一個(gè)新的自定義特性必須派生自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; }
}

該如何拿到我們標(biāo)注的信息呢?這時(shí)候需要使用反射獲取

   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);
     }
   }

執(zhí)行結(jié)果如下:

從執(zhí)行結(jié)果上看,我們拿到了我們想要的數(shù)據(jù),那么這個(gè)特性在實(shí)際使用過程中,到底有什么用途呢?

Attribute特性妙用

在實(shí)際開發(fā)過程中,我們的系統(tǒng)總會(huì)提供各種各樣的對(duì)外接口,其中參數(shù)的校驗(yàn)是必不可少的一個(gè)環(huán)節(jié)。然而沒有特性時(shí),校驗(yàn)的代碼是這樣的:

 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("地址不能為空");
   }

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

首先定義一個(gè)基礎(chǔ)的校驗(yàn)屬性,提供基礎(chǔ)的校驗(yàn)方法

  public abstract class AbstractCustomAttribute : Attribute
  {
    /// <summary>
    /// 校驗(yàn)后的錯(cuò)誤信息
    /// </summary>
    public string ErrorMessage { get; set; }

    /// <summary>
    /// 數(shù)據(jù)校驗(yàn)
    /// </summary>
    /// <param name="value"></param>
    public abstract void Validate(object value);
  }

然后可以定義常用的一些對(duì)應(yīng)的校驗(yàn)Attribute,例如RequiredAttribute、StringLengthAttribute

    /// <summary>
    /// 非空校驗(yàn)
    /// </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>
    /// 自定義驗(yàn)證,驗(yàn)證字符長度
    /// </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);
      }
    }

添加一個(gè)用于校驗(yàn)的ValidateExtensions

public static class ValidateExtensions
 {
   /// <summary>
   /// 校驗(yàn)
   /// </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())
     {
       //需要對(duì)Property的字段類型做區(qū)分處理針對(duì)Object List 數(shù)組需要做區(qū)分處理
       if (item.PropertyType.IsPrimitive || item.PropertyType.IsEnum || item.PropertyType.IsValueType || item.PropertyType == typeof(string))
       {
         //如果是基元類型、枚舉類型、值類型或者字符串 直接進(jìn)行校驗(yàn)
         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))//此處是重點(diǎn)
     {
       //此處是重點(diǎn)
       foreach (AbstractCustomAttribute attribute in property.GetCustomAttributes(typeof(AbstractCustomAttribute), true))
       {
         if (attribute == null)
         {
           throw new Exception("AbstractCustomAttribute not instantiate");
         }

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

新的實(shí)體類

 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; }
 }

調(diào)用方式

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

上面的校驗(yàn)邏輯寫的比較復(fù)雜,主要是考慮到對(duì)象中包含復(fù)雜對(duì)象的情況,如果都是簡單對(duì)象,可以不用考慮,只需針對(duì)單個(gè)屬性做字段校驗(yàn)

現(xiàn)有的方式是在校驗(yàn)不通過的時(shí)候拋出異常,此處大家也可以自定義異常來表示校驗(yàn)的問題,也可以返回自定義的校驗(yàn)結(jié)果實(shí)體來記錄當(dāng)前是哪個(gè)字段出的問題,留待大家自己實(shí)現(xiàn)

如果您有更好的建議和想法歡迎提出,共同進(jìn)步

總結(jié)

到此這篇關(guān)于.NET Attribute在數(shù)據(jù)校驗(yàn)中的應(yīng)用的文章就介紹到這了,更多相關(guān).NET Attribute在數(shù)據(jù)校驗(yàn)的應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • .net后臺(tái)代碼調(diào)用前臺(tái)JS的兩種方式

    .net后臺(tái)代碼調(diào)用前臺(tái)JS的兩種方式

    這篇文章主要介紹了.net后臺(tái)代碼調(diào)用前臺(tái)JS的兩種方式,需要的朋友可以參考下
    2014-03-03
  • 基于.NET Core 3.1 網(wǎng)站開發(fā)和部署的方法

    基于.NET Core 3.1 網(wǎng)站開發(fā)和部署的方法

    這篇文章主要介紹了基于.NET Core 3.1 網(wǎng)站開發(fā)和部署的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • asp.net網(wǎng)站安全從小做起與防范小結(jié)

    asp.net網(wǎng)站安全從小做起與防范小結(jié)

    我是做asp.net網(wǎng)站開發(fā)的,QQ群里一個(gè)網(wǎng)友的站被掛馬了。他說讓我寫點(diǎn)安全方面的文章。我就介紹下我的經(jīng)驗(yàn)吧,各位大牛不要拿磚頭砸我。。。
    2008-09-09
  • SQL Server LocalDB 在 ASP.NET中的應(yīng)用介紹

    SQL Server LocalDB 在 ASP.NET中的應(yīng)用介紹

    如同交響樂一樣,構(gòu)造軟件系統(tǒng)不一定必須某個(gè)強(qiáng)大的明星驅(qū)動(dòng),我們站在歷代ADO.NET的肩膀上,更好地回歸到SQL Server的核心開發(fā):SQL Server LocalDB 在 ASP.NET中的應(yīng)用
    2013-01-01
  • asp.net錯(cuò)誤處理Application_Error事件示例

    asp.net錯(cuò)誤處理Application_Error事件示例

    Application_Error事件與Page_Error事件相類似,可使用他捕獲發(fā)生在應(yīng)用程序中的錯(cuò)誤。由于事件發(fā)生在整個(gè)應(yīng)用程序范圍內(nèi),因此您可記錄應(yīng)用程序的錯(cuò)誤信息或處理其他可能發(fā)生的應(yīng)用程序級(jí)別的錯(cuò)誤
    2014-01-01
  • 運(yùn)行page頁面時(shí)的事件執(zhí)行順序及頁面的回發(fā)與否深度了解

    運(yùn)行page頁面時(shí)的事件執(zhí)行順序及頁面的回發(fā)與否深度了解

    page頁面時(shí)的事件執(zhí)行順序的了解對(duì)于一些.net開發(fā)者起到者尤關(guān)重要的作用;頁面的回發(fā)與否會(huì)涉及到某些事件執(zhí)行與不執(zhí)行,在本文中會(huì)詳細(xì)介紹,感興趣的朋友可以了解下
    2013-01-01
  • Entity Framework管理并發(fā)

    Entity Framework管理并發(fā)

    這篇文章介紹了Entity Framework管理實(shí)現(xiàn)并發(fā)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • asp.net中用DataReader高效率分頁

    asp.net中用DataReader高效率分頁

    自從用Sql2005版本以后一直用ROW_NUMBER()分頁,最近一個(gè)項(xiàng)目維護(hù)sqlserver是2000,沒辦法重寫了分頁。寫完測試分析比ROW_NUMBER()明顯快啊
    2011-09-09
  • asp.net如何進(jìn)行mvc異步查詢

    asp.net如何進(jìn)行mvc異步查詢

    這篇文章主要介紹了asp.net如何進(jìn)行mvc異步查詢,Asp.net mvc 有自己獨(dú)特的優(yōu)勢,有需要的朋友可以來了解一下。
    2016-10-10
  • ASP.NET實(shí)現(xiàn)頁面?zhèn)髦档膸追N方法小結(jié)

    ASP.NET實(shí)現(xiàn)頁面?zhèn)髦档膸追N方法小結(jié)

    這篇文章介紹了ASP.NET實(shí)現(xiàn)頁面?zhèn)髦档膸追N方法,有需要的朋友可以參考一下
    2013-11-11

最新評(píng)論

陇南市| 山阴县| 眉山市| 宁河县| 江达县| 临漳县| 扶风县| 青川县| 双牌县| 玉山县| 禄丰县| 郯城县| 晋城| 乐山市| 莱西市| 客服| 巧家县| 武陟县| 蓝田县| 哈尔滨市| 海兴县| 新干县| 汶上县| 南阳市| 迭部县| 万全县| 延寿县| 义乌市| 松滋市| 哈密市| 盐津县| 临高县| 龙南县| 大石桥市| 灵石县| 延边| 长岛县| 闻喜县| 杭锦后旗| 柏乡县| 景泰县|