Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 8631

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T02:55:10+00:00 2024-11-28T02:55:10+00:00

Adding Validation To The Options Pattern In ASP.NET Core

  • 60k

In this week's newsletter I will show you how to easily add validation to the strongly typed configuration objects injected with IOptions.

The Options pattern allows us to use classes to provide strongly typed configuration values in our application at runtime.

But you have no guarantee that the configuration values injected with IOptions will be correctly read from the application settings.

Let's see how we can introduce validation for IOptions and make sure the application settings are correct.

Strongly Typed Configuration

I first want to define a simple class that will represent our strongly typed configuration. Let's say we want to integrate with the GitHub API, so we create a GitHubSettings class to hold our configuration:

public class GitHubSettings {     public string AccessToken { get; init; }      public string RepositoryName { get; init; } } 
Enter fullscreen mode Exit fullscreen mode

Inside of our appsettings.json file we need to create a section to hold our configuration values:

"GitHubSettings": {     "AccessToken": "access-token-value",     "RepositoryName": "youtube-projects" } 
Enter fullscreen mode Exit fullscreen mode

And with this in place, we can configure our GitHubSettings:

builder.Services.Configure<GitHubSettings>(     builder.Configuration.GetSection("GitHubSettings")); 
Enter fullscreen mode Exit fullscreen mode

Finally, our GitHubSettings is properly configured and we can inject it with IOptions<GitHubSettings>.

What Could Go Wrong?

If we leave the implementation like this, we're moving the responsibility for providing the correct configuration values to the developer. I'm not saying we are the problem, but I've forgotten to add application settings a few times. I'm sure this happened to you also.

Here are just a few things that can go wrong:

  • Passing an incorrect section name to IConfiguration.GetSection
  • Forgetting to add the settings values in appsettings.json
  • Typo in a property name in the class or in the configuration
  • Unbindale properties without a setter
  • Data type mismatch resulting in incompatible values

Depending on which one of these mistakes is made, the application will behave differently at runtime.

The best case scenario is that the incorrect application settings cause a runtime exception, and you realize you have a problem and fix it.

The worst case scenario, and this happens more often than you may think, is that the application silently fails. The application settings aren't correctly set on the value provided by IOptions, but you don't get a runtime exception. The problem may go undetected for some time.

How do we solve this?

Validation For The Options Pattern

There is a simple way to introduce validation to the settings class using data annotations. We just add the validation attributes that we need to the properties of the settings class.

For example, we can add the Required attribute to the GitHubSettingsproperties:

public class GitHubSettings {     [Required]     public string AccessToken { get; init; }      [Required]     public string RepositoryName { get; init; } } 
Enter fullscreen mode Exit fullscreen mode

We have to slightly change how we configure the GitHubSettings:

builder.Services     .AddOptions<GitHubSettings>()     .BindConfiguration("GitHubSettings")     .ValidateDataAnnotations(); 
Enter fullscreen mode Exit fullscreen mode

A few things to note here:

  • AddOptions – returns an OptionsBuilder<TOptions> that binds to the GitHubSettings class
  • BindConfiguration – binds the values from the configuration section
  • ValidateDataAnnotations – enables validation using data annotations

With this in place, if we try to inject GitHubSettings with any of the properties missing a value, we will get a runtime exception.

You can also define a custom delegate for the validation logic, instead of using data annotations:

builder.Services     .AddOptions<GitHubSettings>()     .BindConfiguration("GitHubSettings")     .Validate(gitHubSettings =>     {         if (string.IsNullOrEmpty(gitHubSettings.AccessToken))         {             return false;         }          return true;     }); 
Enter fullscreen mode Exit fullscreen mode

Running Validation At Application Start

It would be great if we could run validation on the configuration values when our application is starting, instead of at runtime.

We can do that by calling ValidateOnStart method when configuring our settings class:

builder.Services     .AddOptions<GitHubSettings>()     .BindConfiguration("GitHubSettings")     .ValidateDataAnnotations()     .ValidateOnStart(); // 👈 the magic happens here 
Enter fullscreen mode Exit fullscreen mode

When we start the application, the validation will run on GitHubSettingsand an exception is thrown if validation fails. The validation exception will look something like this:

Unhandled exception. Microsoft.Extensions.Options.OptionsValidationException:   DataAnnotation validation failed for 'GitHubSettings' members: 
Enter fullscreen mode Exit fullscreen mode

This shortens the feedback loop, and you will know right away that you have a problem. This is much better than finding out that you have a problem at runtime, like in the previous examples.

Closing Thoughts

The Options pattern is very flexible and allows us to use strongly typed settings in ASP.NET Core.

If you want to see how to implement the Options pattern, I made a video about it where I go into the details.I covered the differences between IOptions, IOptionsSnapshot and IOptionsMonitor.

And now you know how to use the ValidateOnStart method, which was introduced in .NET 6, to validate your application settings on app start up. This allows you to learn about configuration issues as soon as possible, instead of at runtime.

I also made a video showing how to add validation to the Option pattern.


P.S. Whenever you're ready, there are 2 ways I can help you:

  1. Pragmatic Clean Architecture: This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. Join 950+ students here.

  2. Patreon Community: Think like a senior software engineer with access to the source code I use in my YouTube videos and exclusive discounts for my courses. Join 820+ engineers here.

aspnetcorecsharpdotnetwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.