How to set-up connection string in appsettings.json

An appsettings.json file keeps key/value pairs of information your app can use. To read the key/value pairs you should work with a file configuration provider. Such provider is the JsonConfigurationProvider class that comes with nuget package Microsoft.Extensions.Configuration.Json

Why we use appsettings.json in c#?

  1. Centralized Application Settings

    Applications often require the same settings to be used in multiple places. By storing these settings in a separate file, we make sure the same value is used consistently throughout the entire project. Every time the setting needs to be updated, you only need to do it once inside the appsettings.json file.

  2. Environment-Specific Configurations

    Most applications have multiple environments, such as “development” and “production”. Development often contains test or inaccurate data. Production on the other hand requires accurate real-world data, which leads to the need for an environment specific database and API for each environment. By keeping settings in the appsettings.json file we can switch between environments by replacing the appsettings.json file or using environment-specific overrides (e.g., appsettings.Development.json).

  3. Enhanced Security

    You can choose not to include your appsettings.json file in source control. This prevents sensitive information, such as API keys or connection strings, from being exposed in your repository.

The ConfigurationBuilder object

In applications whose lifecycle and service management is provided by a .NET Generic Host the ConfigurationBuilder is part of the host object. For Console applications that don't use this approach you need to provide the ConfigurationBuilder object from a nuget package .Net is capable to read key value pair settings from various configuration sources:

  • Settings files, such as appsettings.json
  • Environment variables
  • In-memory .NET objects
  • Command-line arguments
  • Azure Key Vault
  • Azure App Configuration
  • And more...

For each of these configuration providers you will find a different variant of the 'Microsoft.Extensions.Configuration' package. This tutorial is concentrated on Json configuration file and will work with Microsoft.Extensions.Configuration.Json

Hierarchical keys

The structure of a JSON file is hierarchical, where each "value" can itself be another JSON object containing its own set of key-value pairs.

Hierarchical keys image

A hierarchical key is created using a colon (:) to separate the keys at different levels.

Examples of hierarchical keys are: "VolumeSettings:Max", "VolumeSettings:step", "ConnectionString:DefaultConnection"

Create and read an appsettings.json file from class library project

In this guide I will show you how to create a configuration file for your project and add and read a connection string from it.

  1. Create a C# class library project.
  2. Create appsettings.json file at the root level of your class library project. Change the file property "Copy to Output Directory" to "Copy if newer".
    Copy to Output Directory
  3. Add test values inside the appsettings.json
    1{
    2  "Version": "1.0.1",
    3  "VolumeSettings": {
    4    "Max": 10,
    5    "Step": 2
    6  },
    7  "ConnectionStrings": {
    8    "DefaultConnection": "Server=localhost\SQLEXPRESS;..."
    9  }
    10}
  4. Create AppConfiguration class that will read the key value pairs from appsettings.json
    1public static class AppConfiguration
    2{
    3}
  5. Install nuget package Microsoft.Extensions.Configuration.Json
  6. Inside AppConfiguration create one new ConfigurationBuilder object. This object knows how to load and parse json files.
    1public class AppConfiguration
    2{
    3    private IConfigurationRoot configuration;
    4
    5    public AppConfiguration()
    6    {
    7        var builder = new ConfigurationBuilder();
    8        builder.SetBasePath(Directory.GetCurrentDirectory());
    9        builder.AddJsonFile("appsettings.json", optional: true);
    10        this.configuration = builder.Build();
    11    }
    12}
  7. Create methods for pulling different value structures.
    1public class AppConfiguration
    2{
    3    private IConfigurationRoot configuration;
    4
    5    public AppConfiguration()
    6    {
    7        var builder = new ConfigurationBuilder();
    8        builder.SetBasePath(Directory.GetCurrentDirectory());
    9        builder.AddJsonFile("appsettings.json", optional: true);
    10        this.configuration = builder.Build();
    11    }
    12
    13    public string? GetConnectionString(string key)
    14    {
    15        return this.configuration.GetConnectionString(key);
    16    }
    17
    18    public string? GetValue(string key)
    19    {
    20        return this.configuration[key];
    21    }
    22
    23    public T? GetObject<T>(string key)
    24        where T : class, new()
    25    {
    26        var obj = new T();
    27        this.configuration.GetSection(key).Bind(obj);
    28        return obj;
    29    }
    30}
    31

    - The GetConnectionString method reads the keys inside the “ConnectionStrings” object. The method utilises GetConnectionString from IConfigurationRoot. Another approach is to use an hierarchical object key like so:

    1public string? GetConnectionString(string key)
    2{
    3    return this.configuration["ConnectionStrings:" + key];
    4}

    - The GetValue method takes a key or a hierarchical object key and returns the configuration values.

    - With the ConfigurationBuilder object you have the ability to bind configuration sections into C# objects. To add the bind function you must install Microsoft.Extensions.Configuration.BinderAn alternative method also coming from .Binder package is this:

    1public T? GetObject<T>(string key) where T : class, new()
    2{
    3    var obj = configuration.GetRequiredSection(key).Get<T>();
    4    return obj;
    5}

And for an example on how to use these method see the following code

1public class VolumeSettings
2{
3    public int Max { get; set; }
4    public int Step { get; set; }
5}
1static void Main(string[] args)
2{
3    var config = new AppConfiguration();
4    var version = config.GetValue("Version");
5    var connectionString = config.GetConnectionString("DefaultConnection");
6    var section = config.GetObject<VolumeSettings>("VolumeSettings");
7}

Create and read configuration from appsettings.json c# ASP.NET WEB API project using Dependency Injection Container

In the next example, I will create an ASP.NET Core Web API project to demonstrate how to read application settings and connection strings from the appsettings.json file. The example uses .NET 8.

  1. Create ASP.NET Core Web API project
  2. Create one new HomeController inside the Controllers folder
    Create API controller
  3. Appsettings.json file is part of the “ASP.NET Core Web API” template. Add some test variables to it
  4. 1{
    2  "Logging": {
    3    "LogLevel": {
    4      "Default": "Information",
    5      "Microsoft.AspNetCore": "Warning"
    6    }
    7  },
    8  "AllowedHosts": "*",
    9  "Version": "1.0.1",
    10  "VolumeSettings": {
    11    "Max": 10,
    12    "Step": 2
    13  },
    14  "ConnectionStrings": {
    15    "DefaultConnection": "Server=localhost\SQLEXPRESS;..."
    16  }
    17}
  5. Create a Volume class
  6. 1public class Volume
    2{
    3    public const string SectionName = "VolumeSection";
    4    public int Max { get; set; }
    5    public int Step { get; set; }
    6}
    7
  7. Pull IConfiguration from DI
  8. 1private readonly IConfiguration configuration;
    2 public HomeController(IConfiguration configuration)
    3 {
    4     configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
    5 }
    6
  9. Use the configuration object to get a single setting
  10. 1[HttpGet(Name = "home")]
    2public string? Get()
    3{
    4  var version = configuration.GetValue<string>("Version");
    5  return version;
    6}
    7
  11. Use the configuration object to get a section of the settings as a C# object
  12. 1[HttpGet(Name = "home")]
    2public string? Get()
    3{
    4  var version = configuration.GetValue<string>("Version");
    5  return version;
    6}
    7

Unlike console applications, which do not provide built-in configuration options by default, Web API projects include a WebApplication host and a preconfigured dependency injection (DI) container. Within this DI container, a default IConfiguration object is registered. This object is already set up to recognize and load the appsettings.json configuration file.

1[HttpGet(Name = "section")]
2public Volume? GetSection()
3{
4    //Variant 1
5    var section = new Volume();
6    configuration.GetSection(Volume.SectionName).Bind(section);
7
8    //Variant 2
9    var section2 = configuration.GetSection(Volume.SectionName).Get<Volume>();
10    return section2;
11}

Options design pattern

The options design pattern is used to encapsulate application settings by organizing them into logical groups. Each group contains settings that are closely related to one another. These groups are then parsed into C# objects and registered as entities within the dependency injection (DI) container.

  1. Open Program.cs and add the following row
  2. 1builder.Services.Configure<Volume>(builder.Configuration.GetSection(Volume.SectionName));
  3. The volume setting is accessible through IOptions<Volume> object
  4. 1private readonly IConfiguration configuration;
    2        private readonly Volume volumeSetting;
    3        
    4        public HomeController(IConfiguration configuration, IOptions<Volume> volumeSettings)
    5        {
    6            configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
    7            volumeSetting = volumeSettings.Value;
    8        }
  5. To get the connection string value call configuration.GetConnectionString("DefaultConnection");
  6. 1private readonly IConfiguration configuration;
    2private readonly Volume volumeSetting;
    3private readonly string? connectionString;
    4
    5public HomeController(IConfiguration configuration, IOptions<Volume> volumeSettings)
    6{
    7    configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
    8    volumeSetting = volumeSettings.Value;
    9    connectionString = configuration.GetConnectionString("DefaultConnection");
    10}