2015-09-25 61 views
3

在MVC 6项目,我有以下的配置文件...MVC 6配置验证

{ 
    "ServiceSettings" : 
    { 
    "Setting1" : "Value" 
    } 
} 

...和下​​面的类...

public class ServiceSettings 
{ 
    public Setting1 
    { 
    get; 

    set; 
    } 
} 

ConfigureServices方法在Startup类的,我已经添加下面的代码行...

services.Configure<ServiceSettings>(Configuration.GetConfigurationSection("ServiceSettings")); 

如果值是必需的,我如何验证?我可以在实际使用IOptions<ServiceSettings>实例时验证,但如果服务的运行需要Setting1的值,我希望尽可能早地捕获该实例,而不是进一步下游。旧的ConfigurationSection对象允许您指定规则,如果某些内容无效,则会在读取配置数据时抛出异常。

回答

1

我去和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); 
    } 
} 
+0

我已将您的解决方案标记为答案,因为它与我提出的类似(在我阅读您的解决方案之前)。我选择实现IValidatableObject接口而不是属性。在这种情况下,这可能比任何事情都更偏好。 –

3

你可以做类似如下:

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 
+0

我标记了他呃解决方案作为答案,尽管你的解决方案是正确的如果可以的话,我会把两者都标记为答案。谢谢您的意见。 –