Introduction: One Question That Haunts Every .NET Developer
\n\nHave you ever wondered what actually happens when you write ConfigurationManager.AppSettings["myKey"]? Most developers simply take it for granted: you write a string — you get a value. But if you dig a little deeper (and that's exactly what every curious mind does after reading a popular question on Stack Overflow), you'll discover a whole mechanism hidden behind this simple call.
In this article, we won't just show you how to read settings from app.config or web.config in C#. We'll look under the hood: we'll break down how the .NET Framework parses XML, which classes are involved in this process, and why sometimes your settings aren't read (spoiler: the cache isn't the only culprit).
\n\nIf you've ever encountered a situation where ConfigurationManager.AppSettings["ConnectionString"] returns null while the configuration file is right there — this article is for you.
1. Basics: Structure of a Configuration File
\n\nBefore diving into the details, let's recall what a typical app.config (or web.config) looks like. It all starts with the root element <configuration>:
<?xml version="1.0" encoding="utf-8" ?>\n<configuration>\n <appSettings>\n <add key="ApiUrl" value="https://api.example.com"/>\n <add key="TimeoutSeconds" value="30"/>\n </appSettings>\n <connectionStrings>\n <add name="MainDb" connectionString="Server=.;Database=MyDb;Trusted_Connection=true;"/>\n </connectionStrings>\n</configuration>\n\nThis XML file is not just a set of strings. It's a strictly typed structure that .NET interprets in a special way. And this is where the interesting part begins.
\n\n2. How ConfigurationManager Works: From Call to Result
\n\nWhen you call ConfigurationManager.AppSettings["ApiUrl"], the following chain of events occurs:
- \n
- Determining the configuration file. The system determines which file to read. For an application, it's
YourApp.exe.config(located next to the exe), for a web application —web.configin the root. If the file doesn't exist, an empty collection is returned. \n - Loading XML. The file is read as an XML document.
System.Xml.XmlDocumentor the more efficientXmlReaderis used (depending on the .NET version). \n - Finding the section. The
<configuration>element is searched for, then inside it —<appSettings>. \n - Parsing values. Each child element
<add>withkeyandvalueattributes is converted into a key-value pair and placed into aNameValueCollection. \n - Caching. The result is cached. A subsequent call to
ConfigurationManager.AppSettingsdoes not re-read the file — it retrieves data from the cache. \n
Important nuance: caching and changes
\n\nIf you modify app.config while the application is running, ConfigurationManager.AppSettings will not see these changes until the application domain is reloaded. This is one of the most common causes of bugs: "I changed the settings, but the program is still using the old ones!".
To force a re-read of the configuration, you can use ConfigurationManager.RefreshSection("appSettings"), but this is more of a workaround than a solution.
3. Section Handlers: Custom Sections
\n\nYou've probably noticed that in web.config there are not only appSettings, but also system.web, system.net, and others. Each such section is processed by its own section handler — a class that r