MVC 6 配置验证
MVC 6 Configuration Validation
在 MVC 6 项目中,我有以下配置文件...
{
"ServiceSettings" :
{
"Setting1" : "Value"
}
}
...以及以下 class...
public class ServiceSettings
{
public Setting1
{
get;
set;
}
}
在 Startup
class 的 ConfigureServices
方法中,我添加了以下代码行...
services.Configure<ServiceSettings>(Configuration.GetConfigurationSection("ServiceSettings"));
如果需要 Setting1
的值,我该如何验证?我可以在实际使用 IOptions<ServiceSettings>
实例时进行验证,但如果 Setting1
的值对于服务的操作是必需的,我想尽早捕获它而不是进一步下游。旧的 ConfigurationSection
对象允许您指定规则,如果某些内容无效,这些规则将在读取配置数据时抛出异常。
您可以执行以下操作:
services.Configure<ServiceSettings>(serviceSettings =>
{
// bind the newed-up type with the data from the configuration section
ConfigurationBinder.Bind(serviceSettings, Configuration.GetConfigurationSection(nameof(ServiceSettings)));
// modify/validate these settings if you want to
});
// your settings should be available through DI now
我在 ServiceSettings
中的任何强制性属性上卡住了 [Required]
,并在 Startup.ConfigureServices
中添加了以下内容:
services.Configure<ServiceSettings>(settings =>
{
ConfigurationBinder.Bind(Configuration.GetSection("ServiceSettings"), settings);
EnforceRequiredStrings(settings);
})
以及 Startup
的以下内容:
private static void EnforceRequiredStrings(object options)
{
var properties = options.GetType().GetTypeInfo().DeclaredProperties.Where(p => p.PropertyType == typeof(string));
var requiredProperties = properties.Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(RequiredAttribute)));
foreach (var property in requiredProperties)
{
if (string.IsNullOrEmpty((string)property.GetValue(options)))
throw new ArgumentNullException(property.Name);
}
}
使用 ASP.Net-Core 2.0
验证选项的简洁方法
从 netcore2.0
开始,PostConfigure
很合适。这个函数也接受一个配置委托,但最后执行,所以一切都已经配置好了。
// Configure options as usual
services.Configure<MyOptions>(Configuration.GetSection("section"));
// Then, immediately afterwards define a delegate to validate the FINAL options later
services.PostConfigure<MyOptions>(myOptions => {
// Take the fully configured myOptions and run validation checks...
if (myOptions.Option1 == null) {
throw new Exception("Option1 has to be specified");
}
});
如果不怕向配置对象添加更多代码,可以像 Andrew Lock blog 中描述的那样在启动时实施验证。他创建了 NuGet 包以避免自己添加代码。
如果你想探索更多的可能性,还有 ConfigurationValidation 包提供了一些扩展的配置验证功能(自以为是:我是作者)。
如果您正在使用 FluentValidation 进行某些操作,there is possibility 也可以将其用于配置验证。
在 MVC 6 项目中,我有以下配置文件...
{
"ServiceSettings" :
{
"Setting1" : "Value"
}
}
...以及以下 class...
public class ServiceSettings
{
public Setting1
{
get;
set;
}
}
在 Startup
class 的 ConfigureServices
方法中,我添加了以下代码行...
services.Configure<ServiceSettings>(Configuration.GetConfigurationSection("ServiceSettings"));
如果需要 Setting1
的值,我该如何验证?我可以在实际使用 IOptions<ServiceSettings>
实例时进行验证,但如果 Setting1
的值对于服务的操作是必需的,我想尽早捕获它而不是进一步下游。旧的 ConfigurationSection
对象允许您指定规则,如果某些内容无效,这些规则将在读取配置数据时抛出异常。
您可以执行以下操作:
services.Configure<ServiceSettings>(serviceSettings =>
{
// bind the newed-up type with the data from the configuration section
ConfigurationBinder.Bind(serviceSettings, Configuration.GetConfigurationSection(nameof(ServiceSettings)));
// modify/validate these settings if you want to
});
// your settings should be available through DI now
我在 ServiceSettings
中的任何强制性属性上卡住了 [Required]
,并在 Startup.ConfigureServices
中添加了以下内容:
services.Configure<ServiceSettings>(settings =>
{
ConfigurationBinder.Bind(Configuration.GetSection("ServiceSettings"), settings);
EnforceRequiredStrings(settings);
})
以及 Startup
的以下内容:
private static void EnforceRequiredStrings(object options)
{
var properties = options.GetType().GetTypeInfo().DeclaredProperties.Where(p => p.PropertyType == typeof(string));
var requiredProperties = properties.Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(RequiredAttribute)));
foreach (var property in requiredProperties)
{
if (string.IsNullOrEmpty((string)property.GetValue(options)))
throw new ArgumentNullException(property.Name);
}
}
使用 ASP.Net-Core 2.0
验证选项的简洁方法从 netcore2.0
开始,PostConfigure
很合适。这个函数也接受一个配置委托,但最后执行,所以一切都已经配置好了。
// Configure options as usual
services.Configure<MyOptions>(Configuration.GetSection("section"));
// Then, immediately afterwards define a delegate to validate the FINAL options later
services.PostConfigure<MyOptions>(myOptions => {
// Take the fully configured myOptions and run validation checks...
if (myOptions.Option1 == null) {
throw new Exception("Option1 has to be specified");
}
});
如果不怕向配置对象添加更多代码,可以像 Andrew Lock blog 中描述的那样在启动时实施验证。他创建了 NuGet 包以避免自己添加代码。 如果你想探索更多的可能性,还有 ConfigurationValidation 包提供了一些扩展的配置验证功能(自以为是:我是作者)。 如果您正在使用 FluentValidation 进行某些操作,there is possibility 也可以将其用于配置验证。