Validate strongly typed options when using config sections

Kees C. Bakker
Sep 20, 2019 · 3 min read
Sometimes you need to validate what’s in the box.

I like to validate my application configuration upon startup. Especially when doing local development, I want to know which application settings are missing. I also like to know where I should add them. This blog shows how to implement validation of your configuration classes using data annotations.

Use data annotations

The configuration classes were completely rewritten when .NET Core was introduced. We came a long way since the old .config files.

I love how we can now use the options pattern to bind our settings classes. Strongly typed instances are injected as IOptions<T> or IOptionsSnapShot<T> into our services.

Let’s define a settings class and use data annotations to make the fields required:

In ASP.NET we already use data annotation to validate our models. Some better known attributes are: Required, MinLength, MaxLength, Range, StringLength, EmailAddress, Url and RegularExpression.

What does .NET Core provide?

Microsoft introduced a validation method that can validate the options (since .NET Core 2.2). You can use it with data annotations and it can look something like this:

This is what happens when you try to read the Value of the IOptions<T>object:

.NET throws an error upon usage and the error message does not provide many clues on what to do or where to look.

If you, like me, are looking for eager validation on startup, you must wait until the next version:

Eager validation (fail fast at startup) is under consideration for a future release.
Source: Options pattern in ASP.NET Core — Options Validation

So, we need to code something our selves.

PostConfigure to the rescue!

Let’s use PostConfigure to validate the created option and throw an error if something is invalid:

Now, when we run the code, it breaks in (and during) Startup.cs. This is eager validation, and it provides us with an exception that helps to solve the configuration-error.

Extension methods

Your startup can get quite verbose if you have to configure many options in your application. That’s why I’ve created the following extension methods to help set up the configuration and validation of options:

Coming up with a good name for an extension method is usually the hardest part. Normally, I set up options using services.Configure<KafkaOptions>(Configuration.GetSection("Kafka")), so ConfigureAndValidate<KafkaOptions>("Kafka", Configuration) looks good to me.

Example application

Let’s look at an example application. I like to use the appsettings.json to define the configuration of my services. This is the Program.cs:

This setup allows us to use environment-specific configuration files. Next, we’ll set up the loading of the configuration information into an object in the startup.cs:

Note: the configuration is injected in the startup class.

Final thoughts

Because we’ve used config.AddEnvironmentVariables() in our program, the setting values could also come from the environment. Technically, we can add a Kafka__GroupId to satisfy the requirement.

Configuration can come from a myriad of places, not just from the config files. Pointing your fellow developers into the right direction can save a lot of time.

I work as a Lead Developer at, one of the biggest e-commerce companies of the Netherlands. This article is part of our Tech Blog, check it out & subscribe. Looking for a great job? Check our job offers or drop me a line on LinkedIn.

Originally published at on September 20, 2019.


We'll try to keep up and post on the stuff we're doing and discovering. Interesting in working @wehkamp? Check out

Kees C. Bakker

Written by

I work as a Lead Developer for one of the biggest web-shops in the Netherlands: wehkamp. I ❤️ C# and I like to solve nifty problems.


We'll try to keep up and post on the stuff we're doing and discovering. Interesting in working @wehkamp? Check out

More From Medium

More on Backend from wehkamp-techblog

More on Backend from wehkamp-techblog

Single query UPSERTs in PostgreSQL

More on Csharp from wehkamp-techblog

More on Csharp from wehkamp-techblog

There can be only one

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade