In this tutorial, let us learn how to read the configuration file using the ASP.NET Configuration Service. The ASP.NET core configuration systems allow us to add configurations from various sources using providers. It then converts the configurations into a key/value pair. We inject the configuration service into a class and then use the GetSection
, Value
, & GetValue
methods to read the configurations. Also, learn how to parse the types. How to bind the configurations to a class instance. Learn how to use the Options pattern & IOptionsSnapshot to create a strongly-typed options object. Read configurations stored as arrays, read from INI, XML files, command-line arguments, etc.
Table of Contents
- Reading the Configuration
- GetSection, Value, & GetValue methods
- Parsing Value to Type
- Binding to Objects
- Using the Options Pattern
- Use IOptionsSnapshot to read updated data
- Reading Arrays from the Configuration file
- Reading from XML
- Reading from INI file
- Reading from Command-line arguments
- Reading the Environment variables
- Order Matters
- Reference
Reading the Configuration
We use the dependency injection to get the instance of configuration service (using the interface IConfiguration
) in the constructor of the service class or controller class. We can also inject it into the startup class also.
The IConfiguration
interface is available in the namespace Microsoft.Extensions.Configuration
The code is as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private IConfiguration _config; public HomeController(ILogger<HomeController> logger, IConfiguration config ) { _logger = logger; _config = config; } ... } |
Here’s a Sample JSON file with some configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | { "customOptions": { "BoolOption": "True", "NumberOption": "10", "DateOption": "2020-11-08", "complexOption": { "Option1": "Value1", "Option2": "Value2" } } } |
Boolean Values are stored as string True
or False
.
GetSection, Value, & GetValue methods
Use the GetSection
& Value
method to read a setting. Use the colon (:) to separate each section.
1 2 3 | strVal = _config.GetValue<string>("customOptions:complexOption:Option1"); |
You can also chain the getSection
1 2 3 | strVal = _config.GetSection("customOptions").GetSection("complexOption").GetSection("Option1").Value; |
Reading a non existent setting returns NULL. No error is thrown.
1 2 3 | strVal = _config.GetSection("customOptions").GetSection("NotExists").Value; |
Parsing Value to Type
Use parse method to get the correct type
1 2 3 4 5 | boolVal = bool.Parse(_config.GetSection("customOptions:BoolOption").Value); dateVal = DateTime.Parse(_config.GetSection("customOptions:DateOption").Value); numVal = Decimal.Parse(_config.GetSection("customOptions:NumberOption").Value); |
or use the the built in GetValue
method to parse the type.
1 2 3 4 5 | boolVal = _config.GetValue<bool>("customOptions:BoolOption"); dateVal = _config.GetValue<DateTime>("customOptions:DateOption"); numVal = _config.GetValue<Decimal>("customOptions:NumberOption"); |
Another way to use the GetValue
1 2 3 4 5 | strVal = _config.GetValue<string>("customOptions:complexOption:Option1"); strVal = _config.GetSection("customOptions").GetSection("complexOption").GetValue<String>("Option1"); |
Binding to Objects
Reading each & every setting is a little time-consuming. Instead, we can read the entire section of values using the bind method. This also gives us a strongly typed configuration object.
First, create a class whose properties matches the configuration options. The following class has same properties as the appsettings.json
of the previous section.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class customOptionsConfiguration { public Boolean BoolOption { get; set; } public decimal NumberOption { get; set; } public DateTime DateOption { get; set; } public complexOptionsConfiguration complexOption { get; set; } } public class complexOptionsConfiguration { public string Option1 { get; set; } public string Option2 { get; set; } } |
Create an instance of the above class. The use the Bind
method to populate the class with values from the configurations.
1 2 3 4 5 | customOptionsConfiguration _customSettings = new customOptionsConfiguration(); _config.GetSection("customOptions").Bind(_customSettings); |
Or you can use the get
method
1 2 3 | var _customSettings= _config.GetSection("customOptions").Get<customOptionsConfiguration>(); |
Using the Options Pattern
Options Pattern is another way by which we can read the configurations. This helps us to bind it to a class instance & also use DI to inject it into the class constructor.
First, create the class whose properties matches the configuration options as we did it in the previous section on binding to objects
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class customOptionsConfiguration { public Boolean BoolOption { get; set; } public decimal NumberOption { get; set; } public DateTime DateOption { get; set; } public complexOptionsConfiguration complexOption { get; set; } } public class complexOptionsConfiguration { public string Option1 { get; set; } public string Option2 { get; set; } } |
Open the class or controller, where you want to inject the configuration. Import the namespace Microsoft.Extensions.Options
.
1 2 3 | using Microsoft.Extensions.Options; |
Inject the IOptions<T>
where T is the configuration class (customOptionsConfiguration
.) that we want to inject.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class HomeController : Controller { private readonly customOptionsConfiguration _customOptions; public HomeController(IOptions<customOptionsConfiguration> options) { _customOptions = options.Value; } ... ... ... } |
Now, open the startup class.
Use the Configure<ApplicationOptions>
to add the configurations to the service container. Pass the section to read using Configuration.GetSection("customOptions")
, which binds it to that configuration.
1 2 3 4 5 6 7 8 9 10 | public void ConfigureServices(IServiceCollection services) { ... services.Configure<customOptionsConfiguration>(Configuration.GetSection("customOptions")); ... } |
IOptions<T
> does not load the configuration data after the app has started. It is also registered as Singleton and hence can be injected into any service.
Use IOptionsSnapshot to read updated data
To Reload the Configuration on each request, use the IOptionsSnapshot<T>
. In this case, the service is registered as scoped and therefore cannot be injected into Singleton Service.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class HomeController : Controller { private readonly customOptionsConfiguration _customOptions; public HomeController(IOptionsSnapshot<customOptionsConfiguration> options) { _customOptions = options.Value; } ... ... ... } |
Reading Arrays from the Configuration file
Consider the following array of configuration objects in json file.
1 2 3 4 5 6 7 8 9 10 11 12 | "wizards": [ { "Name": "Gandalf", "Age": "1000" }, { "Name": "Harry", "Age": "17" } ] |
The ASP.NET Core adds the keys based on number to each flattened element. It looks like this.
1 2 3 4 5 6 7 | wizards:0:Name= "Gandalf" wizards:0:Age= "1000" wizards:1:Name= "Harry" wizards:1:Age= "17" |
1 2 3 | strVal = _config.GetValue<string>("wizards:0:Name"); |
Reading from XML
The above format, but in XML is as shown below. Create appsettings.xml
in project root folder and paste the following. Also, right-click go to properties and select copy always under the option copy to the output directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?xml version="1.0" encoding="utf-8" ?> <root> <customOptions> <BoolOption>False</BoolOption> <NumberOption>100</NumberOption> <DateOption>2021-11-08</DateOption> <complexOption> <Option1>Value100</Option1> <Option2>Value200</Option2> </complexOption> </customOptions> </root> |
The default loader in ASP.NET Core does not load the XML files. Use the AddXmlFile
extension method to load it in the program.cs.
1 2 3 4 5 6 7 8 9 10 11 12 | public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration( (a, b) => { b.AddXmlFile("appsettings.xml"); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); |
The configuration system ignores the <root>
element.
Reading from INI file
The above format, but in INI is as shown below. Create appsettings.ini
in project root folder and paste the following. Also, right-click go to properties and select copy always under the option copy to the output directory.
1 2 3 4 5 6 7 8 9 10 11 | [customOptions] BoolOption="True" NumberOption="1000" DateOption="2022-11-08" [customOptions:complexOption] Option1="Value1000" Option2="Value2000" |
Use the AddIniFile
extension method to load it in the program.cs.
1 2 3 4 5 6 7 8 9 10 11 12 | public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration( (a, b) => { b.AddIniFile("appsettings.ini"); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); |
Reading from Command-line arguments
The above settings using the Command-line arguments.
1 2 3 | dotnet our.dll --customOptions:BoolOption = True --customOptions:NumberOption = 2000 --customOptions:DateOption = 2022-11-08 --customOptions:complexOption:Option1 = X --customOptions:complexOption:Option2 = Y |
Reading the Environment variables
Refer to the article Environment variables in ASP.NET Core
Order Matters
The Order in which configuration files are loaded is matters. If two configuration sources contain similar keys, the one which loads last wins.
The default configuration loader loads the configuration in the following order.
appsettings.json
- Environment-specific
appsettings.{EnvironmentName}.json
- Environment variables
- Command-line parameters
Reference
Options Pattern in ASP.NET Core
Read More
- Configuration in ASP.NET Core
- Environment variables in ASP.NET Core