如何解决如何在DI设置过程中自动验证来自appSettings.json文件的配置值?
我在.NET Core项目的appSettings.json文件中添加了配置。为了简单起见,我以数据库设置为例。因此,在设置文件中您将拥有
{
"Database": {
"Host": "localhost","Port": 1234,"Database": "myDb","Username": "username","Password": "pw","EnablePooling": true
}
}
在Startup.cs文件中配置服务时,我希望通过依赖项注入来访问那些设置。数据模型是
public class DatabaseSettings
{
public string Host { get; set; }
public ushort Port { get; set; }
public string Database { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public bool EnablePooling { get; set; }
}
我以这种方式配置
private void SetupSettings(IServiceCollection services)
{
ServiceProvider serviceProvider = services.BuildServiceProvider();
IConfiguration configuration = serviceProvider.GetService<IConfiguration>();
IConfigurationSection databaseConfigurationSection = configuration.GetSection("Database");
services.Configure<DatabaseSettings>(databaseConfigurationSection);
}
最后我要验证这些设置。我知道我可以创建实现IValidateOptions
接口的验证器类。
public class DatabaseSettingsValidator : IValidateOptions<DatabaseSettings>
{
private readonly IList<string> failures;
public DatabaseSettingsValidator()
{
failures = new List<string>();
}
public ValidateOptionsResult Validate(string databaseSettingsName,DatabaseSettings databaseSettings)
{
if (databaseSettings == null)
failures.Add($"{databaseSettingsName} are required.");
if (string.IsNullOrEmpty(databaseSettings?.Host))
failures.Add($"{nameof(databaseSettings.Host)} must not be empty.");
if (string.IsNullOrEmpty(databaseSettings?.Database))
failures.Add($"{nameof(databaseSettings.Database)} must not be empty.");
if (failures.Any())
return ValidateOptionsResult.Fail(failures);
return ValidateOptionsResult.Success;
}
}
但是我是否必须创建此类并自行调用Validate
方法?也许有这样的示例代码?
。
services.ValidateConfiguration<IOptions<DatabaseSettings>,DatabaseSettingsValidator>();
因此,您传入配置的设置和验证器以供使用。
解决方法
但是我在为两个问题苦苦挣扎:
有没有一种方法可以收集所有故障,而不是在之后返回 一?因此,您将获得故障列表,而不必进行修复 一个。
我是否必须创建此类并自行调用Validate方法? 也许有这样的示例代码?
services.ValidateConfiguration
();因此,您传入配置的设置 以及要使用的验证器。
是的,我们可以收集所有失败列表并立即显示它们,还可以创建一个包含Validate方法的类。请检查以下步骤:
首先,由于类名称为“ DatabaseSettings ”,因此最好将配置节名称设置为与类名称相同:
{
"DatabaseSettings": {
"Host": "localhost","Port": 1234,"Database": "myDb","Username": "username","Password": "pw","EnablePooling": true
}
}
[注意]如果使用其他名称,则该值可能不会映射到Database Setting类,因此在验证数据时,它们都为空。
第二,使用数据注释方法将验证规则添加到模型属性中。
public class DatabaseSettings
{
[Required]
public string Host { get; set; }
[Required]
public ushort Port { get; set; }
[Required]
public string Database { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
public bool EnablePooling { get; set; }
}
第三,创建一个ServiceCollectionExtensions类,其中包含ConfigureAndValidate方法:
public static class ServiceCollectionExtensions
{
public static IServiceCollection ConfigureAndValidate<T>(this IServiceCollection @this,IConfiguration config) where T : class
=> @this
.Configure<T>(config.GetSection(typeof(T).Name))
.PostConfigure<T>(settings =>
{
var configErrors = settings.ValidationErrors().ToArray();
if (configErrors.Any())
{
var aggrErrors = string.Join(",",configErrors);
var count = configErrors.Length;
var configType = typeof(T).Name;
throw new ApplicationException(
$"Found {count} configuration error(s) in {configType}: {aggrErrors}");
}
});
}
然后,注册ConfigureAndValidate服务:
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureAndValidate<DatabaseSettings>(Configuration);
}
最后,获取“例外”列表。
public class HomeController : Controller
{
private readonly DatabaseSettings_settings;
public HomeController(IOptions<DatabaseSettings> settings)
{
_settings = settings.Value; // <-- FAIL HERE THROW EXCEPTION
}
}
然后,这样的测试结果(我从appSettings.json中删除了主机和用户名):
更多详细信息,您可以查看以下博客:Validating configuration in ASP.NET Core
,ValidateOptions主要用于复杂的情况,使用ValidateOptions的目的是可以将验证逻辑从启动中移出。
我认为对于您的情况,您可以使用以下代码作为参考
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions<MyConfigOptions>()
.Bind(Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.Validate(config =>
{
if (config.Key2 != 0)
{
return config.Key3 > config.Key2;
}
return true;
},"Key3 must be > than Key2."); // Failure message.
services.AddControllersWithViews();
}
有关更多详细信息,请参阅此文档 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1#options-validation
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。