.NET Core MVC - How to Access appsettings.json

Mon, Nov 9, 2020 4-minute read

Well, once again I’ve fallen off of the blogging wagon. And once again I am now getting back on said aforementioned wagon. Let’s try and make this a more regular thing than once a year or so, shall we?

I recently built a quick little hobby site / side project with .NET Core MVC. I have a lot of experience with ASP.NET MVC but I was totally new to .NET Core MVC. As a result, I had to teach myself the new ways of doing old things.

One such lesson (which took me a few hours to learn by the way, even with what I’d call “expert” Google-fu skills) was how to access appsettings.json settings values.

Let me walk you through an apples-to-apples comparison of how it’s done in both MVC frameworks.

The ASP.NET MVC Way - Web.config

ASP.NET MVC uses a Web.config file to store your app settings and provides access to the values via the ConfigurationManager class, particularly the ConfigurationManager.AppSettings property.

Here’s an example of an ASP.NET MVC Web.config file that only contains <appSettings>. We’ll define two settings here that we will use for both ASP.NET and .NET Core:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="WebDomain" value="http://localhost"/>
    <add key="SomeNumber" value="10"/>
  </appSettings>
</configuration>

Accessing these values in code looks something like this:

public static void Test()
{
    string webDomain = ConfigurationManager.AppSettings["WebDomain"];
	int someNumber = int.Parse(ConfigurationManager.AppSettings["SomeNumber"]);
}

Ugly, right? Not only do we use a static class to access things (good luck testing), but we have to explicitly cast our integer in order to use it in code. Gross!

The .NET Core MVC Way - appsettings.json

.NET Core MVC, unlike ASP.NET MVC, has no such Web.config file or ConfigurationManager class. Nonetheless, you can still easily read settings from the appsettings.json file.

Access to appsettings.json values depends on two new concepts: the IOptions<T> interface and the built-in dependency injection of the .NET Core MVC framework.

Here are those same two configuration settings from before, but this time located in the appsettings.json file:

{
  "MySettings": {
    "WebDomain": "http://localhost",
	"SomeNumber": "10"
  }
}

Notice that I nested my settings in a section called MySettings - you can use whatever name you want here, and even define multiple settings under multiple names like so:

{
  "MySettings": {
    "WebDomain": "http://localhost",
	"SomeNumber": "10"
  },
  "SomeOtherSettings": {
	"OtherSetting1": "blah",
	"OtherSetting2": "-1"
  }
}

Accessing these values in code is a little more intimidating at first, but still reasonably simple. First, let’s define a class that represents our settings using strongly-typed public properties:

public class MyOptions
{
	public const string SectionName = "MySettings";

	public string WebDomain { get; set; }
	public int SomeNumber { get; set; }
}

Note that I defined SectionName here as a public const - this is particularly crucial. The value of this string should match the name of your settings section as defined in appsettings.json - in this case "MySettings".

Note also that my property names exactly match the settings names in the appsettings.json file - they must be the same for your settings to be successfully bound to your class. If you don’t name them the same, your settings class will have default property values.

Next we need to wire these settings up in dependency injection. We need to tell the dependency injection system how to connect our appsettings.json values to our new class. We do this in the ConfigureServices method of the Startup class:

public class Startup
{
	public Startup(IConfiguration configuration)
	{
		Configuration = configuration;
	}

	public IConfiguration Configuration { get; }
		
	public void ConfigureServices(IServiceCollection services)
	{
		// Add functionality to inject IOptions<T>
		services.AddOptions();
		// Hook our MyOptions class up to the corresponding appsettings section
		services.Configure<MyOptions>(Configuration.GetSection(MyOptions.SectionName));
	}
}

Now that the DI framework knows what to do, getting our settings is as simple as injecting them into our controller:

public class MyController : Controller
{
	// Inject the IOptions instance into our controller's constructor
	public MyController(IOptions<MyOptions> myOptions)
	{
		string webDomain = myOptions.Value.WebDomain;
		int someNumber = myOptions.Value.SomeNumber;
	}
}

And voila - strongly typed settings accessed via code!

There are lots of other interesting things that you can do with the options paradigm - for example reloading values automatically when the appsettings.json file is modified. Such advanced features are left for you to Google and learn about if needed for your codebase.

Thanks for reading! Hopefully I’ll put out another blog post before November of 2021. ;)