手机版

为ASP.NET核心强类型配置对象添加验证方法

时间:2021-08-28 来源:互联网 编辑:宝哥软件园 浏览:

前言

在这篇博客中,我将描述如何确保当ASP.NET核心程序启动时,强类型配置对象被正确地成功绑定。通过使用IStartupFilter接口对象,您可以更早地验证您的配置对象是否绑定了正确的值,而不需要等到程序启动后的某个时间点再进行验证。

这里我将简要描述ASP.NET核心的配置系统以及如何使用强类型配置。我将主要描述如何消除对IOPs接口的依赖,然后我将描述强类型配置对象没有正确绑定的问题。最后,我将给出一个在程序启动时验证强类型配置对象的方案。

ASP.NET核中的强类型配置

ASP。NET Core的配置系统非常灵活,可以从各种数据源读取配置信息,比如Json文件、YAML文件、环境变量、Azure Key Vault等等。官方建议是使用强类型配置来获取IConfiguration接口对象的值。

强类型配置使用POCO对象来表示程序配置的子集,它不同于IConfiguration接口对象存储的原始键值对。例如,现在您正在将Slack集成到您的程序中,并使用Web钩子向通道发送消息,您需要配置Web钩子的URL和一些其他配置。

公共类slacapesettings { public string WebHookURl { get;设置;}公共字符串DisplayName { get设置;} public bool shouldNotiFication { get;设置;}}可以使用Startup类中扩展方法Configure将强类型配置对象绑定到程序配置。

公共类Startup { public Startup(icon Configuration)配置){ Configuration=configuration}公共图标配置{ get} public void ConfigureServices(IServiceCollection services){ services。AddMvc();服务。配置SlackApiSettings(配置。GetSection(' slackaapi ');} public void Configure(IApplicationBuilder应用程序){ app。UseMvc();}}当需要读取配置时,只需要在当前方法所在类的构造函数中注入一个IOptions接口对象,然后就可以使用这个对象的Value属性来获取配置值。在这里,ASP.NET核心配置系统会自动帮助您完成强类型对象和配置之间的绑定。

公共类test Controller : Controller { private readonly slacapsettings _ slacapsettings;public test controller(iopitionslacapicesettings选项){ _ slackApiSettings=options。Value }公共对象Get(){ return _ slacapizes;}}对IOptions接口的依赖

也许有些人,像我一样,不喜欢让自己的类依赖于IOptions接口。我们只希望我们自己的类只依赖于配置对象。在这里,您可以使用以下方法来消除对IOPs接口的依赖。在这里,我们可以在依赖注入容器中显式注册一个SlackApiSetting配置对象,并将解析它的方法委托给一个IOptions对象

public void ConfigureServices(IServiceCollection services){ services。AddMvc();服务。配置SlackApiSettings(配置。GetSection(' slackaapi ');服务。AddSingleton(解析器=解析器。getrequiredserviceiopitionslacapizens()。价值);}现在,您可以在不引用微软的情况下注入“原始”配置对象。扩展。选项组件。

公共类test Controller : Controller { private readonly slacapsettings _ slacapsettings;public TestController(slacapesettings设置){ _ slackApiSettings=settings} public object Get(){ return _ slacapesettings;}}这个解决方案通常非常有效,但是如果出现配置问题,比如JSON文件中的拼写错误,这里会发生什么?

如果绑定失败,程序会怎么样?

当我们绑定强类型配置对象时,可能会出现几个错误。

节点名称拼错了

绑定配置时,需要显式指定绑定配置节点的名称。如果您当前使用appsetting.json作为配置文件,那么json文件中的键就是配置节点的名称。例如,下面代码中的“日志”和“SlackApi”

{ ' Logging ' : { ' LogLevel ' : { ' Default ' : ' Warning ' },' AllowedHosts': '*,slackaapi ' : { ' webhookull ' : ' http://example.com/test/URL','显示名称' :' myfancybot ',' shouldnotify' 3360 true}}为了将' SlackApi '节点的值绑定到强类型配置对象SlackApiSetting,

服务。配置SlackApiSettings(配置。GetSection(' slackaapi ');此时,假设我们将appsettings.json中的‘slacapi’拼错为‘SackAPI’。现在让我们在前面的例子中调用TestController中的GET方法,我们将得到结果

{“web hook URL”: null,“display name”: null,“should notify”: false }所有键都绑定到它们的默认值,但没有发生错误,这意味着它们绑定到一个空的配置节点。这看起来很糟糕,因为您的代码没有验证webhookUrl是合法的Url。

属性名拼错了

同样,有时节点名称拼写正确,但属性名称可能拼写错误。例如,我们将appSettings.json文件中的“WebhookUrl”拼写为“Url”。此时,我们在前面的示例中调用TestController中的GET方法,我们将得到以下结果

{“web hook URL”: null,“display name”:“my fancybot”,“should notify”: true }强类型配置类的属性缺少SET访问器

我经常发现一些初级程序员会遇到这个问题。对于属性,它们只提供GET访问器,但缺少SET访问器。在这种情况下,强类型配置对象将无法正确绑定。

公共类slacapesettings { public string WebHookURl { get;}公共字符串DisplayName { get} public bool shouldNotiFication { get;}}现在让我们调用前面示例中TestController中的GET方法,我们将得到以下结果

{“web hook URL”: null,“display name”: null,“should notify”: false }不兼容的类型值

最后一种情况是将不兼容的类型值绑定到属性。在配置文件中,所有配置都保存为文本,但活页夹需要将它们转换为中支持的基本类型。NET。例如,ShouldNotify属性是一个布尔值,我们只能将字符串“true”和“false”绑定到该值。但是,如果在配置文件中将该属性的值设置为“值”,程序在访问测试控制器时会报告一个错误。

使用IStartupFilter创建配置验证

为了解决这个问题,我将使用IStartupFilter创建一个简单的验证步骤,在应用程序启动时运行,以确保您的设置是正确的。

IStartupFilter接口允许您通过向依赖注入容器添加服务来间接控制中间件管道。ASP.NET核心框架使用它来执行操作,例如“将IIS中间件添加到应用程序的中间件管道的开头,或者添加诊断中间件”。

虽然IStartupFilter经常用于向管道添加中间件,但我们可能不会这样做。相反,我们可以在程序启动时(服务配置完成后,处理请求前)使用它来执行一些简单的代码。

首先,我们创建一个简单的接口,强类型配置类可以通过实现这个接口来完成一些必要的验证。

公共接口Ivalidatable { void Validate();}接下来,我们创建一个SettingValidationStartupFilter类,它实现了IStartupFilter接口

公共类设置validationstartupfilter : IStartupFilter { readonly ienumeralevalidatable _ validatable objects;public SettingValidationStartupFilter(ienumeralevalidable validatable objects){ _ validatableObjects=validatableObjects;} public ActionIApplicationBuilder Configure(ActionIApplicationBuilder next){ foreach(var validatableObject in _ validatableObjects){ validatableObject .验证();}下一步返回;}}在构造函数中,我们从依赖注入容器中取出了所有实现合法性验证接口的强类型配置对象,并在安装使成形方法中依次调用他们的生效方法。

设置验证开始过滤器并没有修改任何中间件管道,配置方法中直接返回了然后对象。但是如果某个强类型配置类的验证失败,在程序启动时,就会抛出异常,从而阻止了程序。

接下来我们需要在启动类中注册我们创建的服务设置验证开始过滤器

public void ConfigureServices(IServiceCollection services){ services .添加传输开始过滤器,设置验证开始过滤器()//其他配置}最后你需要让你的配置类实现合法性验证接口,我们以SlackApiSettings为例,这里我们需要验证WebhoolUrl和显示名称属性是否绑定成功,并且我们还需要验证WebhoolUrl是否是一个合法的Url。

公共类SLA cape settings : Ivalidatable { public string WebHookURl { get;设置;}公共字符串DisplayName { get设置;} public bool should NotiFication { get;设置;} public void Validate() { if(字符串IsNullOrEmpty(webhookulr)){ 0引发新的异常(' SlackApiSettings .WebhookUrl不能为空或空');}如果(字符串IsNullOrEmpty(display name)){ 0引发新的异常(' SlackApiSettings .WebhookUrl不能为空或空');} //如果不是合法的Url,就会抛出异常var uri=新URi(WebHookURl);}}当然我们还可以使用数据注释属性来实现上述验证。

公共类SLA cape settings : Ivalidatable {[必选,Url]公共字符串WebhookUrl { get设置;}[必需]公共字符串DisplayName { get设置;} public bool should NotiFication { get;设置;}公共void Validate(){ Validator .ValidateObject(this,new ValidationContext(this),validate all properties : true);}}无论你使用哪一种方式,如果绑定出现问题,程序启动时都会抛出异常。

最后一步,我们需要将SlackApiSettings以合法性验证接口的形式注册到依赖注入容器中,这里我们同样可以使用前文的方法解除对吞吐量接口的依赖。

public void ConfigureServices(IServiceCollection services){ services .AddMvc();服务。添加传输开始过滤器,设置验证开始过滤器()服务。配置SlackApiSettings(配置GetSection(' slackaapi ');服务. AddSingleton(解析器=解析器getrequiredservice ioptionslacpizens().价值);服务. AddSingletonIValidatable(解析器=解析器getrequiredservice ioptionslacpizens().价值);}测试结果

我们可以任选之前列举的一个错误方式来进行测试,例如,我们将WebhookUrl错误的拼写为Url。当程序启动时,就会抛出以下异常。

原文:向ASP。网核心中的强类型配置对象添加验证

作者安德鲁洛克:号

译文拉蒙路:号

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

版权声明:为ASP.NET核心强类型配置对象添加验证方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。