Configuration and appsettings.json
Level: Beginner to Intermediate
Configuration is how an ASP.NET Core app reads settings such as database connection strings, logging levels, API keys, feature flags, school year settings, and external service URLs.
- Configuration sources: appsettings.json, appsettings.Development.json, appsettings.Production.json, environment variables, user secrets
appsettings.jsonstructure: JSON file with database, logging, feature flags, API keys (no secrets!)- Environment-specific overrides: appsettings.Development.json overrides appsettings.json when in Development environment
- Connection strings in configuration:
"DefaultConnection": "Server=localhost;Database=SchoolDb" - Reading configuration:
IConfigurationinjected into services, access viaconfig["ConnectionStrings:DefaultConnection"] - User secrets: Store sensitive data (passwords, API keys) outside version control for Development
dotnet user-secretscommand: Set secrets safely without committing to git- Options pattern:
IOptions<DatabaseOptions>for strongly-typed configuration (better than magic strings) - School Management examples: Database connection string, logging level, email credentials, SMS API key
- Environment detection:
app.Environment.IsDevelopment()for different error handling, logging, security settings - Configuration hierarchy: Command-line args > environment variables > appsettings.Environment.json > appsettings.json
- Reloading configuration: Some apps reload settings without restart (feature flags, logging levels)
- Common mistakes: Committing secrets to git, hardcoding sensitive data, wrong environment variable names
What is Configuration?
Configuration is external data your application needs, but should not hard-code.
Examples:
| Setting | Example |
|---|---|
| Database connection | SQL Server connection string |
| Logging level | Information in production, Debug in development |
| File upload limit | 10 MB |
| School name | NexCoding Public School |
| Feature flag | Enable online fee payment |
| API key | SMS provider key |
If these values are hard-coded in C# files, every change requires code editing and redeployment.
Basic appsettings.json
appsettings.json normally lives in the project root.
{
"School": {
"Name": "NexCoding Public School",
"AcademicYear": "2026-2027",
"EnableOnlineAdmissions": true
},
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=SchoolDb;Trusted_Connection=True;TrustServerCertificate=True"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
This is JSON, so:
- property names use double quotes
- commas separate values
- nested objects group related settings
Reading Configuration
ASP.NET Core automatically loads configuration into builder.Configuration.
Nested values are read using colon syntax:
School:Name
Logging:LogLevel:Default
ConnectionStrings:DefaultConnection
IConfiguration in Controllers
[ApiController]
[Route("api/school")]
public class SchoolController : ControllerBase
{
private readonly IConfiguration _configuration;
public SchoolController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet("settings")]
public IActionResult GetSettings()
{
var name = _configuration["School:Name"];
var year = _configuration["School:AcademicYear"];
return Ok(new { name, year });
}
}
This works, but for many settings the Options pattern is cleaner.
Environment-Specific Configuration
ASP.NET Core can load different files based on the environment.
Common files:
appsettings.json
appsettings.Development.json
appsettings.Staging.json
appsettings.Production.json
Base file:
{
"School": {
"Name": "NexCoding Public School",
"EnableOnlineAdmissions": false
}
}
Development override:
{
"School": {
"EnableOnlineAdmissions": true
}
}
In Development, the final value becomes:
School:Name = NexCoding Public School
School:EnableOnlineAdmissions = true
Only the overridden value changes.
Configuration Priority
ASP.NET Core reads configuration from multiple sources. Later sources can override earlier sources.
Common priority:
| Source | Example |
|---|---|
appsettings.json | Base settings |
appsettings.Development.json | Environment override |
| User Secrets | Local developer secrets |
| Environment variables | Server or hosting values |
| Command-line arguments | Runtime overrides |
This is why production can use environment variables without changing source code.
Connection Strings
Connection strings usually go under ConnectionStrings.
{
"ConnectionStrings": {
"SchoolDb": "Server=localhost;Database=SchoolDb;Trusted_Connection=True;TrustServerCertificate=True"
}
}
Read it:
var connectionString = builder.Configuration.GetConnectionString("SchoolDb");
Use it with EF Core:
builder.Services.AddDbContext<SchoolDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("SchoolDb"));
});
Do Not Store Secrets in Git
Do not commit real passwords, API keys, production connection strings, or payment gateway secrets into appsettings.json.
Bad:
{
"Sms": {
"ApiKey": "real-production-key"
}
}
Better for local development:
dotnet user-secrets init
dotnet user-secrets set "Sms:ApiKey" "local-development-key"
Better for production:
Use environment variables or hosting provider secret settings.
Options Pattern
The Options pattern maps configuration into a C# class.
Configuration:
{
"School": {
"Name": "NexCoding Public School",
"AcademicYear": "2026-2027",
"MaxStudentsPerClass": 40
}
}
Settings class:
public class SchoolSettings
{
public string Name { get; set; } = string.Empty;
public string AcademicYear { get; set; } = string.Empty;
public int MaxStudentsPerClass { get; set; }
}
Register:
builder.Services.Configure<SchoolSettings>(
builder.Configuration.GetSection("School"));
Inject:
public class SchoolInfoService
{
private readonly SchoolSettings _settings;
public SchoolInfoService(IOptions<SchoolSettings> options)
{
_settings = options.Value;
}
}
Add namespace:
using Microsoft.Extensions.Options;
When to Use IConfiguration vs Options
| Situation | Better Choice |
|---|---|
Reading one simple value in Program.cs | builder.Configuration |
| Reading many related settings | Options pattern |
| Settings used by services | Options pattern |
| Connection strings | GetConnectionString() |
| Secrets | User Secrets or environment variables |
Common Mistakes
| Mistake | Better Approach |
|---|---|
| Hard-coding connection strings in C# | Store in configuration |
| Committing real passwords | Use User Secrets or environment variables |
| Reading the same config key everywhere | Bind to options class |
| Forgetting environment overrides | Check active environment |
| Misspelling JSON keys | Use strongly typed settings where possible |
Practice Task
Create a configuration section called School.
- Add
Name,AcademicYear, andMaxStudentsPerClass. - Read one value using
builder.Configuration. - Create a
SchoolSettingsclass. - Register it using
Configure<SchoolSettings>(). - Inject
IOptions<SchoolSettings>into a service.
Quick Recap
| Question | Answer |
|---|---|
| Where are app settings stored? | appsettings.json and other configuration sources |
| How do you read nested config? | Configuration["Section:Key"] |
| How do you read connection strings? | GetConnectionString("Name") |
| Where should secrets go? | User Secrets or environment variables |
| What is Options pattern? | Binding config sections to C# classes |
Q: How do you manage configuration in ASP.NET Core?
Good Answer: "ASP.NET Core uses a configuration system that reads values from sources such as appsettings.json, environment-specific JSON files, user secrets, environment variables, and command-line arguments. Configuration can be read through IConfiguration, but for grouped settings the Options pattern is preferred. Sensitive values should not be committed to source control; use User Secrets for development and environment variables or secret stores in production."
Use ChatGPT, Claude, or Copilot to go deeper on Configuration. Try these prompts:
"Explain appsettings.json in ASP.NET Core with an example.""What is the Options pattern and why is it useful?""Where should I store secrets in development and production?""How do environment-specific appsettings files override values?"
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.