如何為ASP.NETCore強類型配置對象添加驗證-創(chuàng)新互聯(lián)

這篇文章主要介紹了如何為ASP.NET Core強類型配置對象添加驗證,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)服務(wù)項目包括蜀山網(wǎng)站建設(shè)、蜀山網(wǎng)站制作、蜀山網(wǎng)頁制作以及蜀山網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,蜀山網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到蜀山省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

ASP.NET Core中的強類型配置


ASP.NET Core的配置系統(tǒng)非常的靈活,它允許你從多種數(shù)據(jù)源中讀取配置信息,例如Json文件,YAML文件,環(huán)境變量,Azure Key Vault等。官方推薦方案是使用強類型配置來獲取IConfiguration接口對象的值。

強類型配置使用POCO對象來呈現(xiàn)你的程序配置的一個子集,這與IConfiguration接口對象存儲的原始鍵值對不同。例如,現(xiàn)在你正在你的程序中集成Slack, 并且使用Web hooks向頻道中發(fā)送消息,你需要配置Web hook的URL, 以及一些其他的配置。

public class SlackApiSettings
{
 public string WebhookUrl { get; set; }
 public string DisplayName { get; set; }
 public bool ShouldNotify { get; set; }
}

你可以在Startup類中使用擴展方法Configure,將強類型配置對象和你程序配置綁定起來。

public class Startup
{
 public Startup(IConfiguration configuration) 
 {
 Configuration = configuration;
 }

 public IConfiguration Configuration { get; }

 public void ConfigureServices(IServiceCollection services)
 {
 services.AddMvc();
 services.Configure<SlackApiSettings>(Configuration.GetSection("SlackApi")); 
 }

 public void Configure(IApplicationBuilder app)
 {
 app.UseMvc();
 }
}

當(dāng)你需要讀取配置的時候,你只需要在你當(dāng)前方法所在類的構(gòu)造函數(shù)中注入一個IOptions接口對象,即可使用這個對象的Value屬性,獲取到配置的值, 這里ASP.NET Core配置系統(tǒng)自動幫你完成了強類型對象和配置之間的綁定。

public class TestController : Controller
{
 private readonly SlackApiSettings _slackApiSettings;
 public TestController(IOptions<SlackApiSettings> options)
 {
 _slackApiSettings = options.Value
 }

 public object Get()
 {
 return _slackApiSettings;
 }
}

解除對IOptions接口的依賴


可能有些人和我一樣,不太喜歡讓自己創(chuàng)建的類依賴于IOptions接口,我們只希望自己創(chuàng)建的類僅依賴于配置對象。這里你可以使用如下所述的方法來解除對IOptions接口的依賴。這里我們可以在依賴注入容器中顯式的注冊一個SlackApiSetting配置對象,并將解析它的方法委托給一個IOptions對象

public void ConfigureServices(IServiceCollection services)
{
 services.AddMvc();

 services.Configure<SlackApiSettings>(Configuration.GetSection("SlackApi")); 

 services.AddSingleton(resolver => 
 resolver.GetRequiredService<IOptions<SlackApiSettings>>().Value);
}

現(xiàn)在你可以在不引用Microsoft.Extensions.Options程序集的情況下,注入了一個“原始”的配置對象了。

public class TestController : Controller
{
 private readonly SlackApiSettings _slackApiSettings;

 public TestController(SlackApiSettings settings)
 {
 _slackApiSettings = settings;
 }

 public object Get()
 {
 return _slackApiSettings;
 }
}

這個解決方案通常都非常有效, 但是如果配置出現(xiàn)問題,例如在JSON文件中出現(xiàn)了錯誤拼寫,這里會發(fā)生什么事情呢?

如果綁定失敗,程序會發(fā)生什么事情?


我們綁定強類型配置對象的時候有以下幾種錯誤的可能。

節(jié)點名稱拼寫錯誤


當(dāng)你綁定配置的時候,你需要顯式的指定綁定的配置節(jié)點名稱,如果你當(dāng)前使用的appsetting.json作為配置文件,json文件中的key即是配置的節(jié)點名稱。例如下面代碼中的"Logging"和“SlackApi”

{
 "Logging": {
 "LogLevel": {
 "Default": "Warning"
 }
 },
 "AllowedHosts": "*",
 "SlackApi": {
 "WebhookUrl": "http://example.com/test/url",
 "DisplayName": "My fancy bot",
 "ShouldNotify": true
 }
}

為了綁定"SlackApi"節(jié)點的值到強類型配置對象SlackApiSetting, 你需要調(diào)用一下代碼

services.Configure<SlackApiSettings>(Configuration.GetSection("SlackApi"));

這時候,假設(shè)我們將appsettings.json中的"SlackApi"錯誤的拼寫為"SackApi"?,F(xiàn)在我們?nèi)フ{(diào)用前面例子中的TestController中的GET方法,會得到一下結(jié)果

{
 "webhookUrl":null,
 "displayName":null,
 "shouldNotify":false
}

所有的key都是綁定了他們的默認(rèn)值,但是沒有發(fā)生任何錯誤,這意味著他們綁定到了一個空的配置節(jié)點上。這看起來非常糟糕,因為你的代碼并沒有驗證webhookUrl是否是一個合法的Url。

屬性名拼寫錯誤


相似的,有時候拼寫的節(jié)點名稱正確,但是屬性名稱可能拼寫錯誤。例如, 我們將appSettings.json文件中的"WebhookUrl"錯誤的拼寫為"Url"。這時我們調(diào)用前面例子中的TestController中的GET方法,會得到以下結(jié)果

{
 "webhookUrl":null,
 "displayName":"My fancy bot",
 "shouldNotify":true
}

強類型配置類的屬性缺少SET訪問器


我經(jīng)常發(fā)現(xiàn)一些初級程序員會遇到這個問題,針對屬性,他們只提供了GET訪問器,而缺少SET訪問器,在這種情況下強類型配置對象是不會正確綁定的。

public class SlackApiSettings
{
 public string WebhookUrl { get; }
 public string DisplayName { get; }
 public bool ShouldNotify { get; }
}

現(xiàn)在我們?nèi)フ{(diào)用前面例子中的TestController中的GET方法,會得到以下結(jié)果

{
 "webhookUrl":null,
 "displayName":null,
 "shouldNotify":false
}

不兼容的類型值


最后一種情況就是將一個不兼容的類型值,綁定到屬性上。在配置文件中,所有的配置都是以文本形式保存的,但是綁定器需要將他們轉(zhuǎn)換成.NET中支持的基礎(chǔ)類型。例如ShouldNotify屬性是一個布爾類型的值,我們只能將"True", "False"字符串綁定到這個值上,但是如果你在配置文件中,設(shè)置該屬性的值為"THE VALUE", 當(dāng)程序訪問TestController時,程序就會報錯

如何為ASP.NET Core強類型配置對象添加驗證

使用IStartupFilter創(chuàng)建一個配置驗證


為了解決這個問題,我將使用IStartupFilter創(chuàng)建一個在應(yīng)用啟動時運行的簡單驗證步驟,以確保你的設(shè)置正確無誤。

IStartupFilter接口允許你通過向依賴注入容器添加服務(wù)來間接控制中間件管道。 ASP.NET Core框架使用它來執(zhí)行諸如“將IIS中間件添加到應(yīng)用程序的中間件管道的開頭, 或添加診斷中間件之類”的操作。

雖然IStartupFilter經(jīng)常用來向管道中添加中間件,但是我們也可以不這么做。相反的,我們可以在程序啟動時(服務(wù)配置完成之后,處理請求之前),使用它來執(zhí)行一些簡單的代碼。

這里首先我們創(chuàng)建一個簡單的接口,強類型配置類可以通過實現(xiàn)這個接口來完成一些必要的驗證。

public interface IValidatable
{
 void Validate();
}

下一步,我們創(chuàng)建一個SettingValidationStartupFilter類, 它實現(xiàn)了IStartupFilter接口

public class SettingValidationStartupFilter : IStartupFilter
{
 readonly IEnumerable<IValidatable> _validatableObjects;
 public SettingValidationStartupFilter(IEnumerable<IValidatable> validatableObjects)
 {
  _validatableObjects = validatableObjects;
 }

 public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
 {
  foreach (var validatableObject in _validatableObjects)
  {
   validatableObject.Validate();
  }

  return next;
 }
}

在構(gòu)造函數(shù)中,我們從依賴注入容器中取出了所有實現(xiàn)IValidatable接口的強類型配置對象,并在Configure方法中依次調(diào)用他們的Validate方法。

SettingValidationStartupFilter并沒有修改任何中間件管道, Configure方法中直接返回了next對象。但是如果某個強類型配置類的驗證失敗,在程序啟動時,就會拋出異常,從而阻止了程序。

接下來我們需要在Startup類中注冊我們創(chuàng)建的服務(wù)SettingValidationStartupFilter

public void ConfigureServices(IServiceCollection services) 
{
 services.AddTransient<IStartupFilter, SettingValidationStartupFilter>()
 // 其他配置
}

最后你需要讓你的配置類實現(xiàn)IValidatable接口, 我們以SlackApiSettings為例,這里我們需要驗證WebhoolUrl和DisplayName屬性是否綁定成功,并且我們還需要驗證 WebhoolUrl是否是一個合法的Url。

public class SlackApiSettings : IValidatable
{
 public string WebhookUrl { get; set; }
 public string DisplayName { get; set; }
 public bool ShouldNotify { get; set; }

 public void Validate()
 {
  if (string.IsNullOrEmpty(WebhookUrl))
  {
   throw new Exception("SlackApiSettings.WebhookUrl must not be null or empty");
  }

  if (string.IsNullOrEmpty(DisplayName))
  {
   throw new Exception("SlackApiSettings.WebhookUrl must not be null or empty");
  }

  // 如果不是合法的Url,就會拋出異常
  var uri = new Uri(WebhookUrl);
 }
}

當(dāng)然我們還可以使用DataAnnotationsAttribute來實現(xiàn)上述驗證。

public class SlackApiSettings : IValidatable
{
 [Required, Url]
 public string WebhookUrl { get; set; }
 [Required]
 public string DisplayName { get; set; }
 public bool ShouldNotify { get; set; }

 public void Validate()
 {
  Validator.ValidateObject(this, 
   new ValidationContext(this), 
   validateAllProperties: true);
 }
}

無論你使用哪一種方式,如果綁定出現(xiàn)問題,程序啟動時都會拋出異常。

最后一步,我們需要將SlackApiSettings 以IValidatable接口的形式注冊到依賴注入容器中,這里我們同樣可以使用前文的方法解除對IOptions接口的依賴。

public void ConfigureServices(IServiceCollection services) 
{
 services.AddMvc();

 services.AddTransient<IStartupFilter, SettingValidationStartupFilter>()

 services.Configure<SlackApiSettings>(Configuration.GetSection("SlackApi")); 

 services.AddSingleton(resolver => 
  resolver.GetRequiredService<IOptions<SlackApiSettings>>().Value);

 services.AddSingleton<IValidatable>(resolver => 
  resolver.GetRequiredService<IOptions<SlackApiSettings>>().Value);
}

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“如何為ASP.NET Core強類型配置對象添加驗證”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

網(wǎng)頁名稱:如何為ASP.NETCore強類型配置對象添加驗證-創(chuàng)新互聯(lián)
文章源于:http://muchs.cn/article28/ceejjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、小程序開發(fā)、網(wǎng)站維護(hù)、網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)