In this article, you will learn six ways to read all settings on the AppSettings.JSON file in an ASP.NET CORE 3.0 web application.
With the ASP.NET CORE, the WEB.CONFIG file was totally out of use, but if you want to Host an ASP.NET CORE Web Application on IIS, you must still use it.
So, we are talking about the AppSettings.JSON file, and there are lots of ways to read it.
Imagine a settings file written this way.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"MySettings": {
"Log": true,
"ConnectionStringId": "Default",
"Parameters": {
"IsProduction": true
}
},
"AllowedHosts": "*"
}
For this article, let’s try to read the IsProduction (bool) property in six different ways. Shall we?
1. AppSettings GetSection
The first simple way is to use the GetSection method from the IConfiguration interface reading parent/child tags like this.
[ApiController]
[Route("[controller]")]
public class Way1Controller : ControllerBase
{
private readonly IConfiguration _configuration;
public Way1Controller(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public bool Get()
{
return bool.Parse(_configuration.GetSection("MySettings").GetSection("Parameters").GetSection("IsProduction").Value); // here
}
}
To reach the IsProduction property, it’s necessary first to read MySettings and Parameters tags.
The property value will return a String with the value “true” the same as configured on the AppSettings.JSON file.
Finally, we need to convert the String value to a Boolean one.
2. AppSettings GetSection e GetValue
The second way is a little bit better than the first one. Just use the GetValue method and be explicit about what type want to convert it to.
[ApiController]
[Route("[controller]")]
public class Way2Controller : ControllerBase
{
private readonly IConfiguration _configuration;
public Way2Controller(
IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public bool Get()
{
return _configuration.GetSection("MySettings").GetSection("Parameters").GetValue<bool>("IsProduction"); // here
}
}
As you can see, automatically converting String to Boolean is very good but still, it has lots of code repetition calling the GetSection method.
3. AppSettings GetValue inline
The third and more elegant way is to write all properties inline and in order, separated by a colon.
[ApiController]
[Route("[controller]")]
public class Way3Controller : ControllerBase
{
private readonly IConfiguration _configuration;
public Way3Controller(
IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public bool Get()
{
return _configuration.GetValue<bool>("MySettings:Parameters:IsProduction"); // here
}
}
You have to agree with me, that way is much better than the other two.
But we are still writing lots of String words on the GetValue method and injecting the IConfiguration interface in the controller’s constructor.
Imagine if we have lots of controllers, we need to repeat this code across all controllers, and this is not a good programming practice.
4. AppSettings GetSection e Binding
The fourth way is to connect (like a binding) one class instance to a corresponding tag in the AppSettings.JSON file.
Let’s create a class called MySettingsConfiguration with the same properties above the MySettings tag in the AppSettings.JSON file.
public sealed class MySettingsConfiguration
{
public bool Log { get; set; }
public string ConnectionStringId { get; set; }
public Parameters Parameters { get; set; }
}
public sealed class Parameters
{
public bool IsProduction { get; set; }
}
Now it’s just to configure the binding between a MySettingsConfiguration instance and the configuration section using the Bind method, check it out.
[ApiController]
[Route("[controller]")]
public class Way4Controller : ControllerBase
{
private readonly MySettingsConfiguration _settings;
public Way4Controller(IConfiguration configuration)
{
_settings = new MySettingsConfiguration();
configuration.GetSection("MySettings").Bind(_settings);
}
[HttpGet]
public bool Get()
{
return _settings?.Parameters?.IsProduction ?? false;
}
}
But we are still using the GetSection method, dependency injection of IConfiguration in the controller’s constructor. We can do better than that!
5. AppSettings IOptions
The next way to read the AppSettings.JSON file is by using the IOptions interface by typing the MySettingsConfiguration class that we created before.
[ApiController]
[Route("[controller]")]
public class Way5Controller : ControllerBase
{
private readonly IOptions<MySettingsConfiguration> _configuration;
public Way5Controller(
IOptions<MySettingsConfiguration> configuration)
{
_configuration = configuration;
}
[HttpGet]
public bool Get()
{
return _configuration.Value?.Parameters?.IsProduction ?? false;
}
}
Remember, to use it that way it’s necessary to perform a small configuration on the Startup.cs file.
public void ConfigureServices(IServiceCollection services)
{
// Way 5
services.Configure<MySettingsConfiguration>(Configuration.GetSection("MySettings"));
services.AddControllers();
}
That is a better way to read the AppSettings.JSON file, but we are still using an ASP.NET CORE internal interface, in this case, the IOptions interface.
It could be interesting that all controllers and business classes don’t use ASP.NET CORE internal references.
6. AppSettings PRE-Binding
In my opinion, the best way to read the AppSettings.JSON file is to inject the MySettingsConfiguration class that we created before.
[ApiController]
[Route("[controller]")]
public class Way6Controller : ControllerBase
{
private readonly MySettingsConfiguration _configuration;
public Way6Controller(MySettingsConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public bool Get()
{
return _configuration.Parameters.IsProduction;
}
}
This way is much more straightforward, and we don’t use any ASP.NET CORE internal interface.
To make this work, it’s necessary one configuration is in the Startup.cs file.
public void ConfigureServices(IServiceCollection services)
{
// Way 6
var mySettings = new MySettingsConfiguration();
new ConfigureFromConfigurationOptions<MySettingsConfiguration>(Configuration.GetSection("MySettings")).Configure(mySettings);
services.AddSingleton(mySettings);
services.AddControllers();
}
That configuration seems too complex to understand, even more, if you need to repeat that code for other tags and classes.
To make it easy and not repeat any code, I created an Extension Method to encapsulate all these code blocks, and it becomes very easy to use it.
public void ConfigureServices(IServiceCollection services)
{
// Way 6 extension
services.AddConfiguration<MySettingsConfiguration>(Configuration, "MySettings");
services.AddControllers();
}
public static class ConfigurationExtension
{
public static void AddConfiguration<T>(
this IServiceCollection services,
IConfiguration configuration,
string configurationTag = null)
where T : class
{
if (string.IsNullOrEmpty(configurationTag))
{
configurationTag = typeof(T).Name;
}
var instance = Activator.CreateInstance<T>();
new ConfigureFromConfigurationOptions<T>(configuration.GetSection(configurationTag)).Configure(instance);
services.AddSingleton(instance);
}
}
That’s it, thank you for reading, and I hope you enjoyed it.
Share and comment if you know other ways to read settings in the AppSettings.JSON file.
Thank you