When working with ASP.NET Core applications, storing configuration settings in the appsettings.json file is common. While the appsettings.json file offers a convenient way to structure configuration data; there is a common need to retrieve this data in a format that facilitates easy manipulation within .NET applications. This is where converting appsettings.json content into a dictionary becomes valuable. In this article, we’ll explore various approaches to get appsettings content as a dictionary.
Before we dive into this topic, we recommend going through our article How to Read AppSettings Values From a JSON File in .NET Core.
With that, let’s start.
Get appsettings.json Content as a Dictionary Using GetSection Method
In ASP.NET Core, the GetSection()
method is a powerful tool within the IConfiguration
interface that enables us to target specific sections within the appsettings.json
file. The GetSection()
method returns an IConfigurationSection
object representing the specified section, providing a convenient way to drill down into the configuration hierarchy.
First, let’s create an object in the appsettings.json
file:
{ "EmailSettings": { "SmtpServer": "smtp.example.com", "Port": 587, "Username": "[email protected]", "Password": "testpassword" } }
Here, we define an EmailSettings
object with four properties.
Let’s start by creating an EmailController
class:
[ApiController] [Route("api/[controller]")] public class EmailController : ControllerBase { private readonly IConfiguration _configuration; public EmailController(IConfiguration configuration) { _configuration = configuration; } [HttpGet("get-dictionary/{sectionName}")] public ActionResult<Dictionary<string, string>> GetAppSettingsAsDictionaryUsingGetSection(string sectionName) { var appSettingsSection = _configuration.GetSection(sectionName); var appSettingsDictionary = appSettingsSection .AsEnumerable() .Where(x => !string.IsNullOrWhiteSpace(x.Value)) .ToDictionary(x => x.Key.Replace("EmailSettings:", ""), x => x.Value); return Ok(appSettingsDictionary); } }
First, we inject the IConfiguration
into the EmailController
constructor. We use IConfiguration
to access the application’s configuration settings, including those in the appsettings.json
file.
Next, we define a GET
endpoint that accepts a parameter sectionName
. Then, we invoke the GetSection()
method using the _configuration
object by passing the sectionName
, which retrieves the AppSettings value from the appsettings.json
file.
Then, we use the AsEnumerable()
extension method to convert the configuration section into an enumerable collection of IConfigurationSection
. It allows us to iterate over the key-value pairs within the configuration section, and we filter out key-value pairs where the value is either null
or consists only of whitespace using the LINQ Where()
extension method.
Finally, we call the ToDictionary()
method to create a dictionary from the filtered key-value pairs. For each key-value pair, we use the Replace()
method to remove the “EmailSettings:” prefix from each key before adding it to the dictionary.
Let’s test the endpoint:
Here, we can see that AppSetting values are returned as a key-value pair format.
Get appsettings.json Content as a Dictionary Using GetChildren Method
The GetChildren()
method is a valuable tool within the IConfigurationSection
interface that allows us to retrieve all child sections under a specific section in the appsettings.json
file. Thus we can utilize it to convert the AppSettings value to a dictionary.
This method is beneficial when dealing with complex configuration structures that organize settings into hierarchical categories.
GetChildren()
method and IConfigurationSection
, please check out our great article How to Get a JSON Array Using IConfiguration in ASP.NET Core.By calling the GetChildren()
method on a specific section, we can obtain an IEnumerable<IConfigurationSection>
representing of all the child sections beneath that specific section. This enables a comprehensive and flexible approach to managing configuration settings, especially in scenarios where dynamic or nested configurations are prevalent.
Let’s create another GET
method inside the EmailController
class:
[HttpGet("get-children-dictionary/{sectionName}")] public ActionResult<Dictionary<string, string>> GetAppSettingsAsDictionaryUsingGetChildren(string sectionName) { var appSettingsSection = _configuration.GetSection(sectionName); var appSettingsDictionary = new Dictionary<string, string?>(); foreach (var child in appSettingsSection.GetChildren()) { appSettingsDictionary[child.Key] = child.Value; } return Ok(appSettingsDictionary); }
We retrieve the AppSettings value using the GetSection()
method. Then, we iterate through each child section by invoking the GetChildren()
method on the appSettingsDictionary
object. We extract key-value pairs from each child section and add them to the dictionary.
Running our application and making a request to this endpoint returns the same result as our previous method.
Convert AppSettings Value to a Dictionary Using the Bind Method
In ASP.NET Core, the Bind()
method is a powerful mechanism for binding configuration data to strongly typed objects. Unlike other approaches that deal with configuration data more dynamically, the Bind()
method provides a structured and type-safe way to map configuration settings directly to properties of a custom configuration class.
Bind()
please visit our ASP.NET Core Configuration – Basic Concepts article.The Bind()
method simplifies the code by reducing the need for manual extraction and conversion of configuration settings, promoting clean and maintainable code.
First, let’s create an EmailSettings
class:
public class EmailSettings { public string? SmtpServer { get; set; } public int Port { get; set; } public string? UserName { get; set; } public string? Password { get; set; } }
Here, we create a Plain Old CLR Object (POCO) class to hold configuration settings related to email functionality.
Then, let’s create a method to convert the POCO class to a dictionary:
private Dictionary<string, object?> ToDictionary(EmailSettings settings) { return settings .GetType() .GetProperties() .ToDictionary(prop => prop.Name, prop => prop.GetValue(_settings, null)); }
We call the GetType()
method, which retrieves the Type
object corresponding to the settings
instance and, subsequently, we chain the GetProperties()
method to obtain the Type
object that produces an array of PropertyInfo
objects, each representing a property within the EmailSettings
class.
Finally, we invoke the LINQ ToDictionary()
method to transform the array into a dictionary.
In essence, we utilize reflection to dynamically generate a dictionary encapsulating the properties and values of the EmailSettings
instance.
Now, we’ll create a GET
method that uses the Bind()
method:
[HttpGet("bind-dictionary/{sectionName}")] public ActionResult<Dictionary<string, object?>> GetAppSettingsAsDictionaryUsingBind(string sectionName) { var settings = new EmailSettings(); _configuration.GetSection(sectionName).Bind(settings); return ToDictionary(settings); }
Here, we create an instance of the EmailSettings
class. Then, we invoke the Bind()
method to map configuration values from the specified section to the properties of the settings
instance.
Finally, we call the ToDictionary()
method by passing the settings
to convert it to a dictionary object.
Get appsettings.json Content as a Dictionary Using the Options Pattern
The Options Pattern in ASP.NET Core provides a flexible and powerful mechanism for configuring and accessing settings in an application. It promotes a clean and modular design by allowing us to encapsulate related configuration settings within a POCO class and inject these settings into services or components requiring them.
By adopting the Options Pattern, we can centralize the configuration of different features or components, making it easier to manage, update, and extend settings. This pattern is handy in scenarios where multiple parts of the application depend on similar configuration options.
We start by registering for the POCO class in the Program
class:
builder.Services.Configure<EmailSettings>(builder.Configuration.GetSection("EmailSettings"));
We establish a connection between the EmailSettings
class and a “EmailSettings” section in the configuration, allowing instances of EmailSettings
to be automatically populated with values from the “EmailSettings” section.
Next, let’s inject the EmailSettings
class in the constructor of the EmailController
:
public class EmailController : ControllerBase { private readonly IConfiguration _configuration; private readonly EmailSettings _settings; public EmailController(IConfiguration configuration, IOptions<EmailSettings> emailSettings) { _configuration = configuration; _settings = emailSettings.Value; } }
Here, we inject the instance of IOptions<EmailSettings>
in the constructor. Then, inside the constructor, we access the Value
property of the IOptions<EmailSettings>
and assign it to the _settings
field. The Value
property retrieves the configured options, in this case, an instance of the EmailSettings
class.
The IOptions<EmailSettings>
interface is part of the Options Pattern in ASP.NET Core, providing a way to access strongly typed configuration settings.
Similarly, let’s define a GET
method:
[HttpGet("options-pattern-dictionary")] public ActionResult<Dictionary<string, object?>> GetAppSettingsAsDictionaryUsingOptions() { return ToDictionary(_settings); }
We invoke the ToDictionary()
method by passing the _settings
instance.
Comparing Different Approaches
So, first up, there’s the GetSection()
method. It’s like the easy-going friend — straightforward, dynamic, and allows us to access configuration data without sweat. But, hold up, it might not be the best choice for complex configurations, and we’ll need to watch out for limited type safety and maybe do a bit of manual conversion.
Now, imagine we have a friend who’s great at handling nested conversations; that’s the GetChildren()
method for hierarchical configurations. It’s flexible and allows dynamic management, but the downside? We’re manually sifting through child sections. It’s a bit more hands-on, but flexibility comes at a price.
Moving on, let’s talk about the Bind()
method. It’s that friend who loves structure and cleanliness. Type safety? Check. Clean and concise code? Absolutely. But here’s the catch — it might be a tad too rigid for dynamic setups, and there’s some extra setup needed.
Finally, there’s the Options Pattern. This one’s like having a modular, organized friend who loves dependency injection. It’s got a clean design, supports dependency injection, and ensures type safety through POCO classes. However, it might be overkill for more straightforward projects and require more setup.
Conclusion
For smaller, simpler projects, a more straightforward approach like using the GetSection() method might be adequate. However, in more extensive and complex projects, the Options Pattern with strongly typed POCO classes and using the Bind() method can offer a structured and maintainable solution.
In this article, we have explored various approaches to get appsettings.json content as a dictionary.