SyntaxStudy
Sign Up
C# Configuration and appsettings.json
C# Beginner 1 min read

Configuration and appsettings.json

.NET's configuration system is provider-based. The default `WebApplication.CreateBuilder` wires up JSON files (appsettings.json and appsettings.{Environment}.json), environment variables, command-line arguments, and user secrets, in increasing order of precedence. All providers funnel their values into a unified `IConfiguration` dictionary. Environment-specific overrides allow a base configuration in appsettings.json to be partially overridden in appsettings.Production.json or appsettings.Development.json. The `ASPNETCORE_ENVIRONMENT` (or `DOTNET_ENVIRONMENT`) environment variable controls which file is loaded, defaulting to `Production` if unset. Secrets management for development uses the User Secrets store (stored outside the project directory) to keep sensitive values like connection strings and API keys out of source control. In production, use environment variables, Azure Key Vault, or AWS Secrets Manager. Never commit secrets to Git.
Example
// Configuration system: appsettings.json + environment variables + IOptions<T>

/*
appsettings.json:
{
  "Logging": { "LogLevel": { "Default": "Information" } },
  "Database": {
    "ConnectionString": "Server=localhost;Database=MyApp;",
    "CommandTimeoutSeconds": 30,
    "MaxPoolSize": 100
  },
  "FeatureFlags": {
    "EnableBetaFeatures": false,
    "MaxUploadSizeMb": 10
  }
}
*/

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

// Strongly-typed option classes
public class DatabaseOptions
{
    public const string Section = "Database";
    public string ConnectionString      { get; set; } = "";
    public int    CommandTimeoutSeconds { get; set; } = 30;
    public int    MaxPoolSize           { get; set; } = 50;
}

public class FeatureFlags
{
    public const string Section = "FeatureFlags";
    public bool EnableBetaFeatures { get; set; }
    public int  MaxUploadSizeMb    { get; set; } = 10;
}

// Wire up in Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddOptions<DatabaseOptions>()
    .Bind(builder.Configuration.GetSection(DatabaseOptions.Section))
    .ValidateDataAnnotations()
    .ValidateOnStart();

builder.Services
    .AddOptions<FeatureFlags>()
    .Bind(builder.Configuration.GetSection(FeatureFlags.Section));

var app = builder.Build();

app.MapGet("/config", (IOptions<DatabaseOptions> db, IOptions<FeatureFlags> ff) =>
    Results.Ok(new
    {
        db.Value.MaxPoolSize,
        db.Value.CommandTimeoutSeconds,
        ff.Value.EnableBetaFeatures,
        ff.Value.MaxUploadSizeMb
    }));

app.Run();