Home » C# » How to read values from appsettings json file in .Net Core 6

How to read values from appsettings json file in .Net Core 6

By Emily

If you’ve built an API anytime recently using .Net Core 6, you’ve probably needed to store some kind of value in your appsettings.json file that you then need in your code. In this post I’ll show you a few ways in which you can read the values from the appsettings file and use them in your code.

Set up the appsettings.json file

First of all we need to build the appsettings.json file – every project comes with a default version prepopulated with some information, and you can add to this and use it however you wish.

Let’s take the following appsettings file which contains :

  1. Three custom values (SectionName, ShowDetails, AllowedHosts)
  2. A connection string called Database which is sitting within the ConnectionStrings section
  3. Some standard Logging configuration
{
  "SectionName": "Detail View", 
  "ShowDetails": true,
  "AllowedHosts": [
      "http://localhost:3000",
      "https://deployed-website-here.com"
    ],
  "ConnectionStrings": {
    	"DevDatabase": "your-connection-string-here"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

This example covers some pretty common use cases for ways in which you might want to use an appsettings file to store configuration or environment specific values:

  1. Storing a custom string or boolean flag which may be different across environments
  2. Storing a list of allowed hosts to use with your CORS policy
  3. Storing a connection string to a database* or an Azure AppConfig instance
  4. Setting different Logging levels in different environments

Name the custom properties

The three custom values have been named by me, and you can call yours whatever you want. However, it’s important to note that the ConnectionStrings name is required to be exactly that. Not ConnectionString singular, it must be the plural version of the word and be spelt exactly like that.

You can define more than one connection string in this section. You may want a database connection here and a connection string for an Azure AppConfig instance. You can call those properties whatever you like, so in the example above, DevDatabase can be changed to any other string, and as long as your code matches the name when you read the value from the appsettings file, everything will work fine.

Get the value from the appsettings file

The simplest way to get a simple configuration value from your file is to use the GetValue<T> method of the WebApplicationBuilder.Configuration property.

var builder = WebApplication.CreateBuilder(args);

.....

//get a string value
string section = builder.Configuration.GetValue<string>("SectionName");

//get a boolean value
bool showDetail = builder.Configuration.GetValue<bool>("ShowDetails");

This works perfectly for a string or a boolean value. However if you use the same code to try and get the array of strings from the AllowedHosts property, you’ll be disappointed, as you just get null returned.

//this does not work!!
string[] allowedHosts = settings.GetValue<string>("AllowedHosts");

How to get an array of strings from an appsettings json configuration file

To get an array of values from the appsettings configuration file you need two lines of code instead of one. First of all we use the GetSection method to grab the whole set of strings as an object, and then use the Get<T> method instead of GetValue<T>.

//get the list of strings as an object
var section = builder.Configuration.GetSection($"AllowedHosts");

//the Get<T> method attempts to bind any value with the given type 
//to the new property, in this case 'values' 
string[] values = section.Get<string[]>();

So far so good. You now know how to get simple values out of the settings file, but it’s a bit …… repetitive. Imagine having 10 or 20 values in there, do you really have to grab them one by one? The good news is, you don’t.

Getting all configuration values in one object

Imagine this more complex appsettings.json file:

{
  "APISettings": {
    "SectionName": "Detail View",
    "ShowDetails": true,
    "AllowedHosts": [
      "http://localhost:3000",
      "https://deployed-website-here.com"
    ],
    "Roles": {
      "User": "Role.User",
      "Admin": "Role.Admin"
    }
  },
  "ConnectionStrings": {
    "AppConfig": "your-appconfig-string-here"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Handling nested configuration values

Up until now I haven’t discussed nested values. To get the value of the ShowDetails property in this example, it changes a little from the first example because the property is now nested inside a Section called APISettings.

bool showDetail = builder.Configuration.GetValue<bool>("APISettings:ShowDetails");

We can still get the value, but the key now changes to a format which is SectionName:PropertyName. I’m mentioning nested properties because they are made much simpler to handle in the this particular method of getting config values.

Create a settings class

To collect all our properties in one go we can define a class which matches the structure and then bind them to it. The class we need to handle the previous appsettings file above needs to be structured like this:

	public class APISettings
    {
        public string SectionName { get; set; }
		public bool ShowDetails { get; set; }
		public string[] AllowedHosts { get; set; }
        public Roles Roles { get; set; }        
    }  

    //Nested classes help manage groups of properties
    public class Roles
    {
        public string User { get; set; } = String.Empty;
        public string Admin { get; set; } = String.Empty;
    }

Once you’ve defined your class that matches the structure of the appsettings file you can now read the values like this:

//Store config settings in one object
var apiSettings = new APISettings();
builder.Configuration.GetSection("APISettings").Bind(apiSettings);

You will now have an object called apiSettings which contains a list of properties containing your configuration values, so you can then use them like this:

//gettng the string value
string section = apiSettings.SectionName;

//gettng the string value
bool details = apiSettings.ShowDetails;

//getting a nested value
string userRoleName = apiSettings.Roles.User;

//your list of allowed hosts can be used in your API CORS set up like this
builder.Services.AddCors(p =>
{
    p.AddPolicy(ApiConstants.CorsPolicy, builder =>
        {
            builder.WithOrigins(apiSettings.AllowedHosts)
                .AllowAnyMethod()
                .AllowAnyHeader();
        });
});

Hopefully you can now design and build your appsettings file and can use the values in the most efficient way in your code.

If you happen to be working in an API which uses Entity Framework then you may want to read this post which describes how to set the environment before running the Add-Migration command.

You may also like to read this post which explains how to implement a global exception handler class in a .Net Core API.