av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

白話EntityFrameworkCore數(shù)據(jù)驗(yàn)證

【稿件】數(shù)據(jù)驗(yàn)證是每個(gè)項(xiàng)目必須存在的,可以防止不符合系統(tǒng)規(guī)范的數(shù)據(jù)進(jìn)入系統(tǒng)進(jìn)而導(dǎo)致系統(tǒng)不穩(wěn)定甚至崩潰。我們可以自己編寫(xiě)代碼(包括前臺(tái)和后臺(tái)代碼)進(jìn)行驗(yàn)證,但是這樣一方面代碼量較大,另一方面有可能驗(yàn)證代碼覆蓋不完全。但是在 Entity Framework Core (以下簡(jiǎn)稱 EF Core )中這些問(wèn)題全可以解決。在 EF Core 中有兩種驗(yàn)證模式,分別是內(nèi)置模型驗(yàn)證和第三方擴(kuò)展模型驗(yàn)證。下面我分別對(duì)這兩種模式進(jìn)行講解,在講解前我們先來(lái)創(chuàng)建必須的模型。

 
 
 
 
  1. public class User
  2. {
  3.     public int Id { get; set; }
  4.     public string Name { get; set; }
  5.     public int Age { get; set; }
  6. }

一、內(nèi)置模型驗(yàn)證

在 EF Core 中并沒(méi)有 Fluent API 模式對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證,因此我們只能通過(guò) Data Annotations (數(shù)據(jù)注解)方式來(lái)進(jìn)行數(shù)據(jù)驗(yàn)證,也就是添加特性的方法來(lái)驗(yàn)證數(shù)據(jù)。例如我們要驗(yàn)證 User 模型中的 Name 的長(zhǎng)度,Name 長(zhǎng)度不能大于 5 ,我們只需在 Name 屬性上增加 StringLength 數(shù)據(jù)注解即可, StringLength 位于命名空間 System.ComponentModel.DataAnnotations 中,修改 User 模型代碼如下:

 
 
 
 
  1. public class User
  2. {
  3.     public int Id { get; set; }
  4.     [StringLength(5)]
  5.     public string Name { get; set; }
  6.     public int Age { get; set; }
  7. }

上述代碼通過(guò) StringLength(5) 數(shù)據(jù)注解將 Name 屬性的數(shù)據(jù)長(zhǎng)度限定在 5 ,并且在數(shù)據(jù)提交時(shí)按照這個(gè)約定進(jìn)行數(shù)據(jù)驗(yàn)證。下面我們就通過(guò)數(shù)據(jù)注解中的驗(yàn)證器來(lái)驗(yàn)證剛才添加的特性。首先我們要?jiǎng)?chuàng)建一個(gè)上下文的擴(kuò)展方法:

 
 
 
 
  1. public static List ExecuteValidation(DbContext context)
  2. {
  3.     List result = new List();
  4.     var models = context.ChangeTracker.Entries()
  5.         .Where(p =>
  6.         (p.State == EntityState.Added) || (p.State == EntityState.Modified));
  7.     foreach (var model in models)
  8.     {
  9.         var entity = model.Entity;
  10.         var valProvider = new ValidationDbContextServiceProvider(context);
  11.         var valContext = new ValidationContext(entity, valProvider, null);
  12.         List error = new List();
  13.         if(!Validator.TryValidateObject(entity,valContext,error,true))
  14.         {
  15.             result.AddRange(error);
  16.         }
  17.         return result.ToList();
  18.     }
  19. }

在上述代碼中我們通過(guò) ChangeTracker 方法找出被追蹤的實(shí)體,然后過(guò)濾出需要添加和更新的實(shí)體,對(duì)這些實(shí)體進(jìn)行數(shù)據(jù)驗(yàn)證。最后我們通過(guò) Validator 中的 TryValidateObject 方法驗(yàn)證實(shí)體數(shù)據(jù)并返回校驗(yàn)錯(cuò)誤信息。在業(yè)務(wù)代碼中我們調(diào)用前面定義的 ExecuteValidation 方法進(jìn)行驗(yàn)證,如果驗(yàn)證通過(guò)就調(diào)用 EF Core 的 SaveChange() 方法,如果未通過(guò)就調(diào)用相應(yīng)的處理代碼,代碼片段如下:

 
 
 
 
  1. if(context.ExecuteValidation().Any())
  2. {
  3.   foreach(var error in context.ExecuteValidation())
  4.   {
  5.     //處理代碼
  6.   }
  7. }
  8. else
  9. {
  10.   context.SaveChange();
  11. }

講到這里估計(jì)會(huì)有很多小伙伴說(shuō)每個(gè)業(yè)務(wù)代碼中都要這么寫(xiě)太麻煩了,而且也產(chǎn)生了大量的重復(fù)代碼。那么重復(fù)代碼這個(gè)問(wèn)題該怎么解決呢?這時(shí)一定有部分小伙伴想到了通過(guò)重寫(xiě) SaveChanges 方法,將驗(yàn)證代碼加入到這個(gè)方法中,這樣就可以解決剛才的那個(gè)問(wèn)題,達(dá)到一勞永逸的效果。具體代碼如下:

 
 
 
 
  1. public override int SaveChanges(bool acceptAllChangesOnSucces)
  2. {
  3.     var provider = ((IInfrastructure)this).Instance;
  4.     var items = new Dictionary();
  5.     var models = this.ChangeTracker.Entries()
  6.         .Where(
  7.         p => (p.State == EntityState.Added)||(p.State==EntityState.Modified));
  8.     foreach (var model in models)
  9.     {
  10.         var entity = model.Entity;
  11.         var context = new ValidationContext(entity, provider, items);
  12.         List results = new List();
  13.         if(!Validator.TryValidateObject(entity,context,results,true))
  14.         {
  15.             foreach (var result in results)
  16.             {
  17.                 if(result!=ValidationResult.Success)
  18.                 {
  19.                     throw new ValidationException(result.ErrorMessage);
  20.                 }
  21.             }
  22.         }
  23.     }
  24.     return base.SaveChanges();
  25. }

通過(guò)上述代碼就可以一處編寫(xiě)驗(yàn)證,多處使用了。具體的思路和前面所講的一樣,這里就不再進(jìn)行講解了。

二、第三方擴(kuò)展模型驗(yàn)證

前面所講的是通過(guò)數(shù)據(jù)注解的方式來(lái)進(jìn)行數(shù)據(jù)驗(yàn)證的,但是如果是使用 Fluent API 的方式就沒(méi)辦法解決文章開(kāi)頭所說(shuō)的問(wèn)題,因?yàn)镕luent API 模式并沒(méi)有提供對(duì)數(shù)據(jù)模型的驗(yàn)證。這時(shí)我們可以使用第三方擴(kuò)展,在 EF Core 中常用的模型數(shù)據(jù)驗(yàn)證第三方擴(kuò)展是 FluentValidation.AspNetCore 。在使用前我們需要在 NuGet 中下載此擴(kuò)展。 FluentValidation.AspNetCore 安裝完成后我們需要為模型創(chuàng)建驗(yàn)證器,驗(yàn)證器是一個(gè)繼承自 AbstractValidator 的類,驗(yàn)證規(guī)則使用 RuleFor 方法定義在驗(yàn)證器構(gòu)造函數(shù)中。代碼如下:

 
 
 
 
  1. public class ModelValidator:AbstractValidator
  2. {
  3.     public ModelValidator()
  4.     {
  5.         RuleFor(p => p.Name).NotEmpty().WithMessage("姓名不能為空");
  6.         RuleFor(p => p.Name).MaximumLength(5).WithMessage("姓名長(zhǎng)度在5字節(jié)");
  7.     }
  8. }

上述代碼進(jìn)行了兩個(gè)驗(yàn)證,一個(gè)是驗(yàn)證 Name 字段是否為空,另一個(gè)是驗(yàn)證 Name 字段的長(zhǎng)度,其中我們通過(guò) MaximumLength 規(guī)定了 Name 字段的最長(zhǎng)長(zhǎng)度為 5 字節(jié)。之后我們通過(guò) WithMessage 方法返回我們自定義的錯(cuò)誤信息。 我們定義完驗(yàn)證規(guī)則后下一步就是將我們定義的驗(yàn)證規(guī)則與應(yīng)用程序連接起來(lái),這里我們需要用到 AddFluentValidation 來(lái)注入,例如在 Asp.Net Core 程序中我們將注入程序?qū)懭?Startup 的 ConfigureServices 方法里。我們調(diào)用 AddFluentValidation 方法會(huì)將 FluentValidation 服務(wù)添加到 Asp.Net Core 中,然后使用 RegisterValidatorsFromAssembly 方法將自定義的驗(yàn)證代碼注入到容器中,代碼段如下:

 
 
 
 
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3.   services.AddMvc()
  4.     .AddFluentValidation(p=>
  5.       p.RegisterValidatorsFromAssemblyContaining());
  6. }

在需要驗(yàn)證數(shù)據(jù)的地方我們通過(guò) ModelState 獲取驗(yàn)證狀態(tài),驗(yàn)證通過(guò)就執(zhí)行后續(xù)代碼,不通過(guò)就執(zhí)行處理代碼。示例代碼如下:

 
 
 
 
  1. if(ModelState.IsValid)
  2. {
  3.   //后續(xù)代碼
  4. }
  5. else
  6. {
  7.   //驗(yàn)證不通過(guò)處理代碼
  8. }

這里有一點(diǎn)需要注意,當(dāng)傳遞的實(shí)體為 null 時(shí),將返回錯(cuò)誤信息,這是因?yàn)?AbstractValidator 中存在 EnsureInstanceNotNull 方法,這個(gè)方法在實(shí)例為 null 時(shí)會(huì)拋出異常,即使重寫(xiě)該方法也無(wú)法返回自定義的錯(cuò)誤信息。如果需要驗(yàn)證實(shí)體集合就需要使用 RuleForEach 方法即可,對(duì)于自定義驗(yàn)證規(guī)則則可使用 SetValidator 方法。

三、總結(jié)

本篇文章講解了 EF Core 數(shù)據(jù)驗(yàn)證的方法,雖然講的是 EF Core 的方法,但是同樣也適用于 EF6 ,這些內(nèi)容是常用的,上述部分代碼可以在大部分項(xiàng)目中通用。

作者簡(jiǎn)介:

朱鋼,筆名喵叔,國(guó)內(nèi)某技術(shù)博客認(rèn)證專家,.NET高級(jí)開(kāi)發(fā)工程師,7年一線開(kāi)發(fā)經(jīng)驗(yàn),參與過(guò)電子政務(wù)系統(tǒng)和AI客服系統(tǒng)的開(kāi)發(fā),以及互聯(lián)網(wǎng)招聘網(wǎng)站的架構(gòu)設(shè)計(jì),目前就職于一家初創(chuàng)公司,從事企業(yè)級(jí)安全監(jiān)控系統(tǒng)的開(kāi)發(fā)。

【原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為.com】


文章名稱:白話EntityFrameworkCore數(shù)據(jù)驗(yàn)證
網(wǎng)頁(yè)路徑:http://uogjgqi.cn/article/coehddg.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流