Options pattern for Validation in ASP .Net Core

Vijay Kumar
3 min readAug 30, 2024

--

Today, we’ll talk about adding validations using Options pattern in ASP .Net Core application.

The Options pattern allows you to bind strongly typed configuration values from appSettings.json at runtime and you can use those values by dependency injection in your code.

Let’s discuss it with an example.

Suppose I have a configuration section in my appSettings.json as follow:

"BlobStorageConfiguration": {
"ConnectionString": "some-connection-string",
"ContainerName": "some-container-name"
}

Now, you want to bind this section to a class called BlobSettings which will represent our strongly type configuration.

public class BlobSettings
{
public string ConnectionString{ get; set; }

public string ContainerName{ get; set; }
}

To bind the configuration section with the BlobSettings class, we can configure it like:

builder.Services.Configure<BlobSettings>(
builder.Configuration.GetSection("BlobStorageConfiguration"));

Now we can use BlobSettings and we can inject it in our code as follows:

public Class CloudService
{
private readonly BlobSettings _blobSettingConfiguration;

CloudService(IOptions<BlobSettings> blobSettingConfiguration)
{
_blobSettingConfiguration = blobSettingConfiguration.Value;
}
}

In this way you will be able to use configuration values using _blobSettingConfiguration in your code.

But, this code has some limitations. What if;

Programmer by mistakenly forgets to add configuration section inside appSettings.json?

If the section is still added but what if he/she forgets to add a property in the configuration section?

There is a data type mismatch happens at runtime which causes runtime issues.

Due to these incorrect configuration issues, application is prone to runtime errors. There can also be the case that application is silently failing and you don’t get any runtime exception.

Let’s see how we can solve this.

Add validations using Options pattern

To add the validations, we can add data annotations in our BlobSettings class which will be validated against configuration values.

Here is an example,

public class BlobSettings
{
[Required]
public string ConnectionString{ get; set; }

[Required]
public string ContainerName{ get; set; }
}

Now we have to slighly enhance our previous code as follows:

builder.Services
.AddOptions<BlobSettings>()
.BindConfiguration("BlobSettings")
.ValidateDataAnnotations();
  • AddOptions returns an OptionsBuilder<TOptions> that binds to the BlobSettings class.
  • BindConfiguration will bind the value from configuration section.
  • ValidateDataAnnotations will do validations using data annotations.

Now if you try to access these values using dependency injection as I have shown earlier, you will get a runtime exception if there is a missing value in configuration.

Now, how about doing this validation on application startup itself. The benefit of this would be that it will do the validation on application startup time itself instead of doing the validation when it is accessed after application has already started. Using this approach, you will get to know on application startup time itself and update the configuration section accordingly instead of getting runtime exceptions after application has already started.

Here is how you can achieve this:

builder.Services
.AddOptions<BlobSettings>()
.BindConfiguration("BlobSettings")
.ValidateDataAnnotations()
.ValidateOnStart();

The method ValidateOnStart() performs the validation on application startup time itself and an exception will be thrown if validation fails. Here you come to know on application startup itself and after that you can add the missing properties or section in configuration of appSettings.json and deploy your application again.

Options pattern is very useful and should be part of your application if you want to perform configuration validations.

Thank you for reading. See you in next article.
Please leave a clap & comment if you like it. It will encourage me to write more.

Vijay Kumar Dhiman

--

--