Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 6 Configuration Validation

In an MVC 6 project, I have the following configuration file...

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

...and the following class...

public class ServiceSettings
{
  public Setting1
  {
    get;

    set;
  }
}

In the ConfigureServices method of the Startup class, I have added the following line of code...

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

If the value of Setting1 is required, how do I validate this? I could validate at the point the IOptions<ServiceSettings> instance is actually used but if the value of Setting1 is necessary for the operation of the service, I would like to catch this as early as possible instead of further downstream. The old ConfigurationSection object let you specify rules that would throw exceptions at the point the configuration data was read if something was invalid.

like image 268
Jason Richmeier Avatar asked Jan 07 '23 12:01

Jason Richmeier


2 Answers

You could do something like the following:

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
like image 151
Kiran Avatar answered Jan 11 '23 08:01

Kiran


I went and stuck [Required] over any mandatory properties in ServiceSettingsand added the following in Startup.ConfigureServices:

services.Configure<ServiceSettings>(settings =>
{
    ConfigurationBinder.Bind(Configuration.GetSection("ServiceSettings"), settings);

    EnforceRequiredStrings(settings);
})

And the following to 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);
    }
}
like image 42
Stafford Williams Avatar answered Jan 11 '23 08:01

Stafford Williams