C# – Read a custom config section from app.config

In this this article, I’ll show the simplest to get a custom config section from app.config and load it into your own config class. You can implement IConfigurationSectionHandler and use ConfigurationManager.GetSection() to do this. I’ll show the steps below.

1 – Add a custom config class

The first step is to create a class that’ll hold whatever configuration values you want to put in app.config. Here’s a simple config class:

public class WeatherClientConfig
{
	public bool IsEnabled { get; set; }
	public string WeatherAPIUrl { get; set; }
	public string Timeout { get; set; }
}
Code language: C# (cs)

2 – Implement IConfigurationSectionHandler to load the section

Implement IConfigurationSectionHandler.Create() to load the section into an object:

  • Use reflection to match the target type with the section name.
  • Use XmlSerializer to deserialize the section XML to the target type.

This is called by ConfigurationManager.GetSection() (which you’ll use in the final step).

using System;
using System.Configuration;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

public class CustomConfigLoader : IConfigurationSectionHandler
{
	public object Create(object parent, object configContext, XmlNode section)
	{
		if (section == null)
		{
			throw new ArgumentNullException($"XMLNode passed in is null.");
		}

		var type = AppDomain.CurrentDomain.GetAssemblies()
		.SelectMany(a => a.GetTypes())
		.FirstOrDefault(t => t.Name == section.Name);

		if (type == null)
		{
			throw new ArgumentException($"Type with name {section.Name} couldn't be found.");
		}

		var serializer = new XmlSerializer(type, new XmlRootAttribute(section.Name));

		using (XmlReader reader = new XmlNodeReader(section))
		{
			return serializer.Deserialize(reader);
		}
	}

}

Code language: C# (cs)

Notice that this works on any type, not just the config class that was added in step 1.

3 – Add the custom config section in app.config

You need to add a section in configSections. Then you can add an XML representation of your config class in app.config. Take a look at the highlighted sections in the app.config below:

Note: If configSections is missing, add the whole configSections node. If it’s already in there, just add the section node within the configSections node.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="WeatherClientConfig" type="WeatherClient.CustomConfigLoader, WeatherClient" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <WeatherClientConfig>
    <IsEnabled>true</IsEnabled>
    <WeatherAPIUrl>https://localhost:12345</WeatherAPIUrl>
    <Timeout>5000</Timeout>
  </WeatherClientConfig>
</configuration>
Code language: HTML, XML (xml)

The <WeatherClientConfig> node matches the config class from step 1.

Explaining the <section> node in app.config

The <section> node basically means: “I want to use this config loader to load this custom XML section.” Take a look at the <section> node again:

<section name="WeatherClientConfig" type="WeatherClient.CustomConfigLoader, WeatherClient" />
Code language: HTML, XML (xml)

This means: “I want to use the WeatherClient.CustomConfigLoader class from assembly WeatherClient to load custom section WeatherClientConfig.”

  • name = The name of the custom section XML node (i.e. <WeatherClientConfig>).
  • type = The type info for the class that implements IConfigurationSectionHandler. Format: Namespace.Class, Assembly.

If the name or type doesn’t match, it throws a ConfigurationErrorsException.

4 – Use ConfigurationManager.GetSection()

Now that all the pieces are in place, load the config section by calling ConfigurationManager.GetSection():

static void Main(string[] args)
{
	var config = (WeatherClientConfig)ConfigurationManager.GetSection(nameof(WeatherClientConfig));

	Console.WriteLine(config.WeatherAPIUrl);
	Console.WriteLine(config.IsEnabled);
	Console.WriteLine(config.Timeout);
}
Code language: C# (cs)

This outputs the following, exactly what you would expect, since it’s what’s in the app.config:

https://localhost:12345
True
5000Code language: plaintext (plaintext)

Code repository

The code shown here is available in this public repository: https://github.com/makolyte/AppConfigLoaderExample.

Comments are closed.