Configuration Files
Vaibhav • September 10, 2025
As your applications grow beyond simple console programs, they often need to remember settings - things like file paths, user preferences, API keys, or feature flags. Hardcoding these values directly into your code is brittle and inflexible. Instead, we use configuration files - external files that store settings in a structured format. In this article, we’ll explore how to work with configuration files in C#, including reading and writing INI, JSON, and XML formats using only the concepts we’ve covered so far.
Why Use Configuration Files?
Configuration files allow your application to be customized without recompiling. For example, you might want to change the logging level, switch between test and production databases, or enable/disable features - all without touching the source code.
Benefits include:
- Separation of code and configuration
- Easy updates and environment-specific settings
- Support for automation and deployment
C# supports multiple configuration formats, but we’ll focus on three common ones: INI, JSON, and XML.
INI Files - Simple Key-Value Settings
INI files are one of the oldest configuration formats. They’re simple, human-readable, and organized into sections. Here’s an example:
[AppSettings]
Theme=Dark
MaxUsers=100
EnableLogging=true
Each section is marked by square brackets, and each setting is a key-value pair. While .NET doesn’t have
built-in support for INI files, you can parse them manually using StreamReader
and string operations.
Dictionary<string, string> settings = new();
foreach (string line in File.ReadLines("config.ini"))
{
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("["))
continue;
string[] parts = line.Split('=');
if (parts.Length == 2)
{
settings[parts[0].Trim()] = parts[1].Trim();
}
}
Console.WriteLine($"Theme: {settings["Theme"]}");
This reads each line, skips empty lines and section headers, splits key-value pairs, and stores them in a dictionary. You can then access settings by key.
Writing INI Files
Writing an INI file is just writing plain text. You can use StreamWriter
to
output the structure:
using StreamWriter writer = new StreamWriter("config.ini");
writer.WriteLine("[AppSettings]");
writer.WriteLine("Theme=Light");
writer.WriteLine("MaxUsers=50");
writer.WriteLine("EnableLogging=false");
This creates a new INI file with updated settings. You can also write comments using ;
or #
.
JSON Files - Structured and Modern
JSON (JavaScript Object Notation) is the most popular format for configuration today. It’s structured, supports nested objects, and is widely used in web APIs and cloud services. Here’s a sample:
{
"AppSettings": {
"Theme": "Dark",
"MaxUsers": 100,
"EnableLogging": true
}
}
To read JSON in C#, you can use the built-in System.Text.Json
namespace. Let’s
define a class to match the structure:
public class AppSettings
{
public string Theme { get; set; }
public int MaxUsers { get; set; }
public bool EnableLogging { get; set; }
}
public class Config
{
public AppSettings AppSettings { get; set; }
}
Now read the file and deserialize it:
using System.Text.Json;
string json = File.ReadAllText("config.json");
Config config = JsonSerializer.Deserialize<Config>(json);
Console.WriteLine($"Theme: {config.AppSettings.Theme}");
This loads the JSON file, maps it to your class structure, and gives you typed access to settings. It’s clean, safe, and easy to extend.
Writing JSON Files
You can also serialize objects back to JSON using JsonSerializer
:
Config config = new Config
{
AppSettings = new AppSettings
{
Theme = "Light",
MaxUsers = 50,
EnableLogging = false
}
};
string json = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText("config.json", json);
This creates a nicely formatted JSON file. The WriteIndented
option makes it
human-readable.
XML Files - Verbose but Powerful
XML (eXtensible Markup Language) is another structured format, used heavily in older .NET applications and enterprise systems. Here’s an example:
<AppSettings>
<Theme>Dark</Theme>
<MaxUsers>100</MaxUsers>
<EnableLogging>true</EnableLogging>
</AppSettings>
You can read XML using XmlDocument
or XDocument
. Let’s use XmlDocument
for simplicity:
using System.Xml;
XmlDocument doc = new XmlDocument();
doc.Load("config.xml");
string theme = doc.SelectSingleNode("/AppSettings/Theme").InnerText;
int maxUsers = int.Parse(doc.SelectSingleNode("/AppSettings/MaxUsers").InnerText);
bool enableLogging = bool.Parse(doc.SelectSingleNode("/AppSettings/EnableLogging").InnerText);
Console.WriteLine($"Theme: {theme}");
This reads values using XPath expressions. You can also navigate nodes manually or use LINQ to XML for more advanced scenarios.
Writing XML Files
To write XML, use XmlWriter
or build a string manually. Here’s a basic example:
using XmlWriter writer = XmlWriter.Create("config.xml");
writer.WriteStartDocument();
writer.WriteStartElement("AppSettings");
writer.WriteElementString("Theme", "Light");
writer.WriteElementString("MaxUsers", "50");
writer.WriteElementString("EnableLogging", "false");
writer.WriteEndElement();
writer.WriteEndDocument();
This creates a well-formed XML file with the desired settings. You can also add attributes, comments, and namespaces if needed.
Choosing the Right Format
Each format has its strengths:
- INI - simple, lightweight, good for small apps
- JSON - modern, structured, ideal for web and cloud
- XML - verbose, but powerful for enterprise and legacy systems
For most new applications, JSON is the preferred choice due to its balance of readability and structure.
Best Practices for Configuration Files
Configuration files are critical to your app’s behavior. Treat them with care:
- Keep them outside your source code (e.g., in a
config
folder) - Use version control to track changes
- Validate values before using them
- Use environment-specific configs (e.g.,
appsettings.Development.json
) - Never store secrets (like passwords or API keys) in plain text
Use a layered configuration approach - default settings in code, overridden by config files, and finally by environment variables. This gives flexibility and security.
Real-World Use Case: Theme Switcher
Let’s build a simple app that reads a theme setting from a JSON file and applies it:
public class AppSettings
{
public string Theme { get; set; }
}
string json = File.ReadAllText("config.json");
AppSettings settings = JsonSerializer.Deserialize<AppSettings>(json);
if (settings.Theme == "Dark")
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
}
else
{
Console.BackgroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Black;
}
Console.Clear();
Console.WriteLine($"Theme applied: {settings.Theme}");
This reads the theme from config and updates the console colors accordingly. You can extend this to support more settings or UI themes.
Summary
Configuration files are a vital part of building flexible, maintainable applications. In this article, you learned how to read and write INI, JSON, and XML files using basic C# techniques. You explored how to parse key-value pairs, deserialize structured data, and build real-world workflows like theme switching and backups. These skills will help you build apps that adapt to different environments, users, and requirements - all without changing your code. In the next chapter, we’ll dive into generics and type safety - unlocking the power of reusable, strongly typed components.