Validate appsettings in ASP.net Core using FluentValidation
Introduction
In the ASP.net core all the application
configurations are maintained in appsettings.json. The appsettings.json
contains many settings like database connections strings, logging settings, and
authentication settings etc. Applications settings are injected into the
application as IConfiguration. Application uses these settings to perform
certain tasks. For example establishing a connection to database. What happens
when you update a wrong database connection string settings in your
appsettings.json file? Shouldn’t we validate the settings before establishing a
connection to database? This article shows you how to validate the
appsettings.json while application starts.
Why should we validate appsettings.json?
There are some benefits validating
appsettings.json,
·
Centrally manage the validations
Applications settings are
consumed in many parts of the
application. The validations of these settings are scattered across the code. Instead
we can centrally manage those validations at one place.
·
Validate before application starts
It is the best practice to
validate the application setting even before the application starts. We don’t
have to wait until the application finds that there is an issue with the
settings deep inside the somewhere in our code flow.
Validate appsettings.json using FluentValidation
FluentValidation is a .NET library for
building strongly-typed validation rules. It uses a fluent interface and lambda
expressions for building validation rules. It helps clean up your domain code
and make it more cohesive, as well as giving you a single place to look for
validation logic.
Predominantly FluentValdiation is used to
validate API input request model. We use FluentValidation for validating
appsettings.json as well.
More on FluentValidation can be read at https://fluentvalidation.net/
Figure
1 Components of Validation
Let us assume that we have to add few
authorization settings in appsettings.json. Below is the model for ‘AuthSettings’,
public class AuthSettings
{
public AuthSettings(){}
public string
Provider { get; set; }
public string Secret
{ get; set; }
public string Issuer
{ get; set; }
public string
Audience { get; set; }
public int
ExpirationMinutes { get; set; }
}
Here is how the AuthSettings will look like
in our appsettings.json,
"AuthSettings": {
"Provider": "AzureAD",
"Secret": "Some
Secret",
"Issuer": "http://someauthorizationurl.com",
"Audience": "http://
someauthorizationurl.com",
}
The
validator for ‘AuthSettings’ is
follows,
public class AuthSettingsValidator : AbstractValidator<AuthSettings>
{
public AuthSettingsValidator()
{
When(authsettings
=> authsettings != null, () =>
{
RuleFor(x => x.Secret)
.NotEmpty();
RuleFor(x => x.Issuer)
.NotEmpty();
RuleFor(x => x.Audience)
.NotEmpty();
RuleFor(x => x.ExpirationMinutes)
.NotEmpty();
});
}
}
Our ‘AuthSettingsValidator’ uses fluent validation and validates ‘AuthSettings’ model.
Below is the generic method for validation,
private static void Validate<T, U>(string
section, IConfiguration configuration) where T : class where U : new()
{
var
settings = configuration.GetSection(section).Get<T>();
if (settings == null)
{
throw new Application.Exceptions.ValidationException("Configuration", $"{nameof(section)} not
found");
}
var
validator = (IValidator<T>)new U();
var
validationResult = validator.Validate(settings);
if (validationResult.Errors.Count > 0)
{
throw new Application.Exceptions.ValidationException(validationResult);
}
}
The generic validation method take two
template T and U, where T is the model to be validated and U is the validator
class for T.
The method creates a validator object and
invokes Validate() method,
var validator = (IValidator<T>)new U();
var validationResult = validator.Validate(settings);
If there is any validation error, the method
raises the ‘ValidationException’.
The below extension method shows how to use
the generic validate method to validate a specific section in out
appsettings.json,
public static IHostBuilder UseConfigValidation(this IHostBuilder hostbuilder,
IConfiguration configuration)
{
Validate<AuthSettings, AuthSettingsValidator>("AuthSettings", configuration);
return hostbuilder;
}
The method is called from the host builder
as follows,
public static IHostBuilder CreateHostBuilder(string[]
args, IConfiguration config) =>
Host.CreateDefaultBuilder(args)
.UseConfigValidation(config)
.ConfigureWebHostDefaults(webBuilder
=>
{
webBuilder.UseStartup<Startup>();
});
The below screen grab shows when ‘ValidationException‘ was thrown,
Figure
2 Screen grab shows when ValidationExcption was thrown
Summary
The source code for the above can be downloaded at this github url, https://github.com/arunvambur/ValidateAppsettings
Comments
Post a Comment