

When you create a (non-web) .NET Framework application in Visual Studio, an app.config file is added to your project. When you create a class library or a .NET Core project, such a file is not included, although it can be done afterward.
What Is It?
The app.config file is an XML file whose goal it is to contain any variable configuration of your application. It is a central place to put:
- Connection strings to databases
- Connection details to external services
- Application settings
- Other details on how the application should be run and/or hosted
What Does It Look Like?

You can start typing under the <configuration> section and Visual Studio’s Intellisense will provide you with the possible options:
The most well-known sections are “appSettings” and the “connectionStrings”.
AppSettings
AppSettings provide an easy way to access string values, based on a certain key. Take these appSettings for example:
We can access this value by using this piece of code:
As a side note: you will need to import the System.Configuration namespace too, by adding “using System.Configuration” at the top of your file.
A possible problem with AppSettings is that we will get back a string. Yet in the above example, we’re clearly working with an integer. We will have to parse the value for it to be more meaningful. Another issue is that there is no compile-time checking that we entered the correct key, as it is just a string.
If your needs are simple, you could be fine with this. If things start to get a little more complicated, you might want to look into “Settings”, which I’ll cover later.
ConnectionStrings
The connectionStrings section is the place to put your connection strings to any databases you want to access. This is a simple example:
Notice how there is also a “providerName”. This tells ORM libraries like Entity Framework which provider they should be using. The provider will differ depending on the database you’re trying to access (e.g. SQL Server, PostgreSQL, MariaDB, etc.).
If you need to access the connection string directly, you can use code like this:
Settings
Remember how the AppSettings only provided us with string values? The Settings system was introduced in .NET 2.0 to improve this. To use this, double click the properties of your project:
Then go to the settings tab. In the beginning, your project will not yet have a default settings file, so click on the link to create one. You’ll see a nice UI where you can define your settings, their values, scopes, and types:
I’ve added our “pollInterval” in these settings, and now I can access it like this:
The nice thing is that we have compile-time checking now, and we’re sure the “pollInterval” variable is an integer.
The Settings system has now created two new files under the Properties folder: Settings.Designer.cs and Settings.settings. You do not need to look into these files, and it’s best not to change them manually. They are automatically generated, so any changes will be overwritten anyway.
The result of these two files is a class containing the settings as properties. By the way, you can change the access (public or internal) by using the dropdown in the Settings tab of the project properties.
Working with the Settings system will also alter your app.config. In the above example, our app.config now includes this:
For more on the .NET settings system and the difference in scopes, check out the MSDN documentation.
Custom Configuration Sections
There is a next step in app.config possibilities: custom configuration sections. These merit a separate article, so I will only cover them here shortly.
As I mentioned at the beginning of this article, a class library doesn’t contain an app.config file. But sometimes, the author of a class library might want to allow other developers to configure certain parts of the library in the host’s app.config file.
One option would be for the author to document the necessary AppSettings. But the AppSettings have the disadvantages I’ve already mentioned, and they don’t allow for any deeper hierarchy.
Custom configuration sections give the class library author the solution to this. When the author has set it all up correctly, the developer using the library can add something like this to the app.config file:
<configuration> <configSections> <sectionGroup name="pageAppearanceGroup"> <section name="pageAppearance" type="Samples.AspNet.PageAppearanceSection" allowLocation="true" allowDefinition="Everywhere" /> </sectionGroup> </configSections> ... <pageAppearanceGroup> <pageAppearance remoteOnly="true"> <font name="TimesNewRoman" size="18"/> <color background="000000" foreground="FFFFFF"/> </pageAppearance> </pageAppearanceGroup> </configuration>
This is taken from the .NET docs, and even though it concerns ASP.NET, the same mechanism is used in classic desktop apps.
As you can see in the above example, the developer using the library
- first defines a new sectionGroup under the configSections tag
- then defines a section under that, pointing to the correct type that will handle the config section
- and finally provides the configuration details.
You can see that the pageAppearance is more complex than the simple AppSettings or Settings sections can handle.
As I said, this is beyond the purpose of this article, but I encourage you to check out the documentation I linked to above.
There’s More
So far, we’ve only covered application settings. But we can consider connection strings as a sort of application setting too.
But the app.config file can contain more than that. Remember how a default app.config contained this:
This is where we define which .NET runtime(s) the application supports. You could change this if your application needs to run on other (higher or lower) runtimes.
The assemblyBinding tag is another tag you will encounter easily. In short, it allows you to point to a certain version of an assembly, even when a different version is required. Again, this is out of the scope of this article, but the documentation should help you further.
Another example is the system.serviceModel tag, which is the place to configure any connections to WCF services.
What Happens When We Compile This?
Good, by now you know what the app.config is for and how to use it. Now you might be wondering what happens behind the scenes. Well, when you compile your application, the compiler actually copies the app.config file to the output folder, but gives it another name:
When you start your application (ConsoleApp1.exe in our example), the matching config file will be loaded too.
It is possible to change this file while the application is running, but you will need to restart the application for the changes to take effect. Luckily, there are ways around this:
- A call to ConfigurationManager.RefreshSection(“…”) will reload the given section
- For applicationSettings, you will need to call Properties.Settings.Default.Reload();
Keep in mind that a new compilation or deployment can overwrite the changed values. So it’s better to make the changes in your source code (which is under source control, right?) and redeploy.
Secrets
You should consider not putting confidential information in your config files. Things like passwords and API keys should be kept out of the app.config file. In an age where more and more code is made open source, you could risk exposing your secrets to the outside world. Even if your repository is private, it’s a best practice to put the secrets elsewhere. First, if you find it normal to do so, you won’t do it when you’re working on a public and open source project. But second, you never know when your private repository may become public, on purpose or by accident.
You can easily solve this by putting your secrets in separate files:
See how both the appSettings and the connectionStrings point to another file? Also note that we can combine an external file with appSettings, but for connectionStrings we need to choose.
If we make sure we don’t put these files under source control, they can remain absolutely private. Another thing to remember is to tell the compiler to copy these files to the output directory:
After that, you can use the appSettings and connectionStrings in your code like you did before.
A Final Tip
In all other locations of your code, you can now call this class and be sure you’re getting an integer.
Happy Configuring!
This article aimed at showing you the basics of the app.config file, and some best practices. The app.config file is a basic piece of the .NET Framework, yet I’ve seen several projects putting their configuration in other places (like plain text files or the registry). Unless you have a very good reason to do so, it’s more convenient and familiar to use the app.config file. You can change it easily, the .NET Framework supports it out of the box and almost all .NET developers know how it works.
Learn more how CodeIt.Right can help you automate code reviews and improve the quality of your code.
15 Comments. Leave new
Very helpful article — thank you! I’m curious though: can you use the settings tab (in the Property Designer) to set the Connection String? Or must you manually edit the app.Config file for that?
[…] is the exract of the article written by Peter Morlion of […]
[…] for your staging or production environments. It?s common for these settings to reside in a XML or Json file, then be deployed along-side the software itself. Within code we can then access them […]
Peter, how are the secrets kept from prying eyes, if the app.SECRETS.config still needs to be deployed to the output directory?
I don’t like the fact that this file is not designed it to be different for production and release right from the start. Once upon a time, old application development environments didn’t provide configuration files out of the box. You have to think for this, and when you did, you usually consider you real-case scenario, that was having a deveolpment set of configuration (often a database connection) and a production configuration (often just placeholders for connection parameters). Now they push us in the direction of a standardized configuration file but they don’t think to the fact that is potentially dangerous to release a development configuration file. You have to resort to solutions that, as you can see on the internet range from visual studio extensions to custom transfomrations to batch files to replace the app.config before releasing. This is the major problem that i would like to be discussed.
XML sucks. This crap is derived from a tool (SGML) used to do type setting on laser printers before the era of WYSIWYG.
And now like free radicals it creeps in every piece of software and corrupts it.
This is the most inefficient tool for configuration purposes, the effective payload is less than 60% of the file,
tags taking more space than the data it encapsulates. And it’s not composable if you have a schema in your way.
Not having support for other formats (JSON, YAML, properties) and better configuration composition today is idiotic and short sighted.
Don’t tell me that IDEs take care of this. Once integrated by an IDE, that ‘feature’ rigidify like a cold corpse.
Microsoft what are you waiting for ? 🙄👈
At least XML has a schema validator that hasn’t been in beta for YEARS and then there is XPath, XSLT, X* etc. that is quite usefull. Space is no problem since we are living in a terabyte world and it compressed to virtually the same size. btw, it is infimitely composible too.
But JSON is cool too.
Sorry, forgot to mention .NET Core supports JSON and many other config formats too now.
Schema validation sucks.
This tightly binds producers and consumers.
In this moving app world it’s like dragging huge anchor chains while trying to run a 100 meters race.
😬
Compression is just a Bandaid.
A flawed tool was chosen and compression is not an answer to enhancing it’s usefulness.
Most studies agree that this choice has a significant processing cost everywhere.
very good
Where is the security logic?
Thank you very much. It is a really amazing article.
Please help newbie, How do i change the following so that ‘value’ = path of the current solution instead of it being hardcoded
<EFin.My.MySettings>
C:\Users\abcd\Desktop\EFin\EFin\EFin\Styles\Office2013_White.isl
</EFin.My.MySettings>
thank you…..
connection you help with vb.net windows form connection string