日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
白話EntityFrameworkCore數(shù)據(jù)驗(yàn)證

【稿件】數(shù)據(jù)驗(yàn)證是每個項(xiàng)目必須存在的,可以防止不符合系統(tǒng)規(guī)范的數(shù)據(jù)進(jìn)入系統(tǒng)進(jìn)而導(dǎo)致系統(tǒng)不穩(wěn)定甚至崩潰。我們可以自己編寫代碼(包括前臺和后臺代碼)進(jìn)行驗(yàn)證,但是這樣一方面代碼量較大,另一方面有可能驗(yàn)證代碼覆蓋不完全。但是在 Entity Framework Core (以下簡稱 EF Core )中這些問題全可以解決。在 EF Core 中有兩種驗(yàn)證模式,分別是內(nèi)置模型驗(yàn)證和第三方擴(kuò)展模型驗(yàn)證。下面我分別對這兩種模式進(jìn)行講解,在講解前我們先來創(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 中并沒有 Fluent API 模式對數(shù)據(jù)進(jìn)行驗(yàn)證,因此我們只能通過 Data Annotations (數(shù)據(jù)注解)方式來進(jìn)行數(shù)據(jù)驗(yàn)證,也就是添加特性的方法來驗(yàn)證數(shù)據(jù)。例如我們要驗(yàn)證 User 模型中的 Name 的長度,Name 長度不能大于 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. }

上述代碼通過 StringLength(5) 數(shù)據(jù)注解將 Name 屬性的數(shù)據(jù)長度限定在 5 ,并且在數(shù)據(jù)提交時按照這個約定進(jìn)行數(shù)據(jù)驗(yàn)證。下面我們就通過數(shù)據(jù)注解中的驗(yàn)證器來驗(yàn)證剛才添加的特性。首先我們要創(chuàng)建一個上下文的擴(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. }

在上述代碼中我們通過 ChangeTracker 方法找出被追蹤的實(shí)體,然后過濾出需要添加和更新的實(shí)體,對這些實(shí)體進(jìn)行數(shù)據(jù)驗(yàn)證。最后我們通過 Validator 中的 TryValidateObject 方法驗(yàn)證實(shí)體數(shù)據(jù)并返回校驗(yàn)錯誤信息。在業(yè)務(wù)代碼中我們調(diào)用前面定義的 ExecuteValidation 方法進(jìn)行驗(yàn)證,如果驗(yàn)證通過就調(diào)用 EF Core 的 SaveChange() 方法,如果未通過就調(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. }

講到這里估計會有很多小伙伴說每個業(yè)務(wù)代碼中都要這么寫太麻煩了,而且也產(chǎn)生了大量的重復(fù)代碼。那么重復(fù)代碼這個問題該怎么解決呢?這時一定有部分小伙伴想到了通過重寫 SaveChanges 方法,將驗(yà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. }

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

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

前面所講的是通過數(shù)據(jù)注解的方式來進(jìn)行數(shù)據(jù)驗(yàn)證的,但是如果是使用 Fluent API 的方式就沒辦法解決文章開頭所說的問題,因?yàn)镕luent API 模式并沒有提供對數(shù)據(jù)模型的驗(yàn)證。這時我們可以使用第三方擴(kuò)展,在 EF Core 中常用的模型數(shù)據(jù)驗(yàn)證第三方擴(kuò)展是 FluentValidation.AspNetCore 。在使用前我們需要在 NuGet 中下載此擴(kuò)展。 FluentValidation.AspNetCore 安裝完成后我們需要為模型創(chuàng)建驗(yàn)證器,驗(yàn)證器是一個繼承自 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("姓名長度在5字節(jié)");
  7.     }
  8. }

上述代碼進(jìn)行了兩個驗(yàn)證,一個是驗(yàn)證 Name 字段是否為空,另一個是驗(yàn)證 Name 字段的長度,其中我們通過 MaximumLength 規(guī)定了 Name 字段的最長長度為 5 字節(jié)。之后我們通過 WithMessage 方法返回我們自定義的錯誤信息。 我們定義完驗(yàn)證規(guī)則后下一步就是將我們定義的驗(yàn)證規(guī)則與應(yīng)用程序連接起來,這里我們需要用到 AddFluentValidation 來注入,例如在 Asp.Net Core 程序中我們將注入程序?qū)懭?Startup 的 ConfigureServices 方法里。我們調(diào)用 AddFluentValidation 方法會將 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ù)的地方我們通過 ModelState 獲取驗(yàn)證狀態(tài),驗(yàn)證通過就執(zhí)行后續(xù)代碼,不通過就執(zhí)行處理代碼。示例代碼如下:

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

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

三、總結(jié)

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

作者簡介:

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

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


網(wǎng)站欄目:白話EntityFrameworkCore數(shù)據(jù)驗(yàn)證
文章位置:http://www.5511xx.com/article/coehddg.html