Select Page
Read Configuration values in ASP.NET Core

Read Configuration values in ASP.NET Core

In this article, we will learn about how to read configuration values in ASP.NET Core. We normally have many settings in our application which are different for each environment like third party service URLs, database connection string, email settings, log parameters, etc. We normally set these values in some configuration files so that we are able to change these values without the need to recompile the application.

ASP.NET Core uses appsettings.json file for such settings and this file is read when the application starts. Also, we can configure to read code to read these settings even after startup, i.e. we can change values even when the application is running.

Ins ASP.NET Core there is more than one source to read configuration values from like Environment variables, settings file, command-line arguments, directory files, in-memory objects, etc.

This article will cover how to read configuration values from appsettings.json file using options pattern.

Options Pattern

Option pattern uses classes to bind a group of related configuration settings to a strong typed access i.e. class will have properties that correspond to some setting in the configuration file. These classes are registered in the dependency injection containers to be injected into services, controllers, etc using constructor dependency injection.

Options pattern helps in keeping settings of the different sections separate i.e. setting for logging can be separate from setting for database connectivity.

For details on dependency injection, you can read my other article on Dependency Injection in ASP.NET Core 3.1

Type of options interfaces

There are 3 type of interfaces supported by options pattern

IOptions<TOptions> – Reads configuration data once when the application starts and any changes in configuration will require the application to be restarted. It is registered in the dependency injection container with a singleton lifetime.

IOptionsSnapshot<TOptions> – Reads configuration on every request. Any changes in configuration while the application is running will be available for new requests without the need to restart the application. It is registered in the dependency injection container as a scoped lifetime. Being a scoped service it receives current options values at the time the object is constructed.

IOptionsMonitor<TOptions> – It is a combination of IOptions & IOptionsSnapshot. Supports re-binding configuration but it is only when configuration changes and not on every request like IOptionsSnapshot. It is registered in the dependency injection container as a singleton lifetime (same as IOptions).

Once options pattern is configured then it can be injected via dependency injection using one of the available interfaces.

Implement Options Pattern

For a demonstration of options pattern to read configuration values in ASP.NET Core, we will be creating a Web API project and read configuration file values using options pattern

Create ASP.NET Core Project

Create ASP.NET Core Web API Project

Add Parameters to appsettings.json

Lets add some sample settings in appsettings.json file to be read using IOptions Pattern

{
  "ApplicationParameters": {
    "SQLServerConnection": "SQL Server Connection String",
    "EmailServer": "127.0.0.1",
    "ServiceURL": "https://procodeguide.com/getpost",
    "MaxLimitUsers": 3000
  }
}

We have added setting section named ApplicationParameters & have added four parameters under it i.e. SQLServerConnection, EmailServer, ServiceURL & MaxLimitUsers

Add properties class

We will add properties class which corresponds to the settings specified in appsettings.json ApplicationParameters section.

public class ApplicationParameters
{
    public string SQLServerConnection { get; set; }
    public string EmailServer { get; set; }
    public string ServiceURL { get; set; }
    public long MaxLimitUsers { get; set; }
}

Bind configuration to your class in Startup class

Let’s add service in startup class to read configuration values into an instance of properties class ApplicationParameters.

public class Startup
{
    public Startup(IWebHostEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        Configuration = builder.Build();
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.Configure<ApplicationParameters>(
            this.Configuration.GetSection("ApplicationParameters"));
    }
    //Remaining code has been removed
}

The default order in which values are read from JSON file is

  1. appsettings.json
  2. appsettings.{environment}.json

i.e. if same key exists in both appsettings.json & appsettings.{environment}.json then on runtime it should display the value from appsettings.{environment}.json

Add a controller to read parameters using IOptions

The sample controller has been added to inject configuration in constructor injection using IOptions & IOptionsSnapshot interfaces. It has one action index which return values of configuration parameters read using IOptions & IoptionsSnapshot

[Route("api/[controller]")]
[ApiController]
public class AppParamtersController : ControllerBase
{
    private ApplicationParameters applicationParameters;
    private ApplicationParameters applicationParametersSnapshot;
    public AppParamtersController(IOptions<ApplicationParameters> options, IOptionsSnapshot<ApplicationParameters> optionsSnap)
    {
        applicationParameters = options.Value;
        applicationParametersSnapshot = optionsSnap.Value;
    }

    [HttpGet]
    public IActionResult Index()
    {
        StringBuilder response = new StringBuilder();
        response.AppendLine("IOptions ==>");
        response.AppendLine(JsonConvert.SerializeObject(applicationParameters));
        response.AppendLine("");
        response.AppendLine("IOptionsSnapshot ==>");
        response.AppendLine(JsonConvert.SerializeObject(applicationParametersSnapshot));
        return Content(response.ToString());
    }
}

Run & Test the code

When we run the code and navigate to path api/AppParamters/Index then configuration values are displayed for IOption & IOptionsSnapshot. Both values match as it has been read when the app started.

IOptions Test Results 1

Now without stopping application modify values in appsettings.json to new values & save changes

Modified appsetting.json

Now refresh browser (without restarting application) and check values for both IOptions & IOptionsSnapshot. You will see that only IOptionsSnapshot contains the latest modified values as it is designed to read values before each request

IOptions Test Results 2

IOptionsMonitor also works in a way similar to IOptionsSnapshot only difference being in the IOptionMonitor service lifetime is Singleton instead of Scoped as in IOptionsSnapshot.

Guidelines for storing configuration values

  • All sensitive data like passwords, personal information should never be stored in plain text in configuration i.e. if at all it is being stored in configuration then it should be encrypted.
  • As far as possible production secrets should be different from development & staging secrets.
  • Use different naming conventions for configuration files on different environments like appsettings.development.json and appsettings.production.json.

Summary

We saw how to read configuration values in ASP.NET Core using IOtions Pattern. We can inject IOption into service, controller, etc using constructor injection.

There are 3 types of IOptions interface IOptions, IOptionsSnapshot & IOptionsMonitor. IOptionsSnapshot & IOptionsMonitor allows you to read modified parameters even while the application is running.

References: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1

Download Source Code

Here is the source code for demonstration of Options Pattern in ASP.NET Core