Previous Securing an ASP.NET Core Web API NET Core vs .NET Framework Next

Configuration and Environment Management in .net core

Configuration and environment management in .NET Core is designed to be flexible, secure, and scalable—perfect for modern cloud-native applications. Here's a comprehensive guide to how it works:

🧾 Common Configuration Sources

  • appsettings.json and appsettings.{Environment}.json
  • Environment variables
  • Command-line arguments
  • User secrets (for development)
  • Azure Key Vault / Azure App Configuration
  • In-memory collections
  • Custom providers

🌍 Managing Multiple Environments in ASP.NET Core

🔧 What Are Environments?

ASP.NET Core supports multiple runtime environments like Development, Staging, and Production. These environments allow you to configure your app differently based on where it's running.

⚙️ Setting the Environment

  • Environment Variable: Set ASPNETCORE_ENVIRONMENT to Development, Staging, or Production.
  • launchSettings.json: Located in Properties folder for local development.
"profiles": {
  "MyApp": {
    "commandName": "Project",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Development"
    }
  }
}
  

📁 Environment-Specific Configuration

Use separate configuration files:

  • appsettings.json – base settings
  • appsettings.Development.json
  • appsettings.Staging.json
  • appsettings.Production.json

These files are automatically loaded based on the current environment.

🧠 Accessing Environment in Code

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}
  

🛠 Custom Environments

You can define custom environments like Testing or UAT and check them using:

if (app.Environment.IsEnvironment("UAT"))
{
    // UAT-specific logic
}
  

✅ Best Practices

  • Keep secrets and sensitive settings out of source code
  • Never store secrets in source-controlled files.
  • Validate configuration at startup to catch issues early.
  • Use environment-specific logging and error handling
  • Automate deployment with environment variables
  • Use CI/CD pipelines to manage environment transitions
  • Use IOptions<T> with strongly typed classes for cleaner access.

📌 Summary

ASP.NET Core makes it easy to configure and manage multiple environments using environment variables, configuration files, and conditional logic. This helps ensure your app behaves appropriately across development, testing, and production stages.

To configure and manage multiple environments in ASP.NET Core, you use a combination of environment variables and structured configuration files. At a high level, you create separate appsettings.{EnvironmentName}.json files and set the ASPNETCORE_ENVIRONMENT variable to tell the application which file to use.

Step 1: Create Environment-Specific Configuration Files

By default, an ASP.NET Core project includes appsettings.json and appsettings.Development.json. You can create additional files for other environments, such as staging or production. Settings in environment-specific files override the base appsettings.json file.

Example File Structure:

  • appsettings.json (base settings for all environments)
  • appsettings.Development.json (overrides for the Development environment)
  • appsettings.Staging.json (overrides for the Staging environment)
  • appsettings.Production.json (overrides for the Production environment)

Example appsettings.Development.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=DevelopmentDb;..."
  }
}

Step 2: Set the ASPNETCORE_ENVIRONMENT Variable

ASP.NET Core applications read the ASPNETCORE_ENVIRONMENT variable at startup to determine the current environment.

To set the variable:

  • In Visual Studio: Modify the launchSettings.json file inside the Properties folder. This is used only for local development and overrides any system-level environment variables.
"profiles": {
  "MyProject": {
    "commandName": "Project",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Development"
    }
  },
  "StagingProfile": {
    "commandName": "Project",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Staging"
    }
  }
}
  • On the server: Set the ASPNETCORE_ENVIRONMENT variable in your hosting environment (IIS, Azure, Docker).
  • IIS: Configure it in the web.config file or in IIS Manager for the app pool.
  • Docker: Set it in your Dockerfile or docker-compose.yml.
  • Azure App Service: Add a new Application Setting named ASPNETCORE_ENVIRONMENT in the Azure portal.

Step 3: Access Configuration in Your Code

ASP.NET Core's built-in dependency injection provides the IConfiguration and IHostEnvironment services to access configuration settings and determine the current environment at runtime.

Using IConfiguration to Retrieve Settings:

// In a controller or service, inject IConfiguration
public class MyService(IConfiguration configuration)
{
    private readonly string _connectionString = configuration.GetConnectionString("DefaultConnection");

    public void DoSomething()
    {
        // Use the connection string dynamically based on the current environment
    }
}

Using IHostEnvironment for Environment-Specific Logic:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage(); // Show detailed errors in development
    }
    else
    {
        app.UseExceptionHandler("/Error"); // Generic error page in production
    }

    if (env.IsEnvironment("Staging"))
    {
        // Add staging-specific middleware
    }
}

Advanced Environment Management

  • Environment-specific service registration: Conditionally register services using if (env.IsDevelopment()) inside ConfigureServices.
  • Centralized configuration: Use Azure App Configuration or HashiCorp Vault to manage and retrieve settings dynamically for multiple applications.
  • Configuration key hierarchy: Environment variables take precedence over JSON settings, and environment-specific JSON overrides the base appsettings.json.

🔐 Azure Key Vault Setup in .NET Core

This walkthrough explains how to set up Azure Key Vault and bind configuration to a custom class in .NET Core. This is a powerful approach for managing secrets securely and accessing them cleanly in your application.

Step 1: Create Key Vault in Azure

  1. Go to Azure Portal → Search for “Key Vault” → Click “Create”.
  2. Fill in details such as name, resource group, and region.
  3. Click Review + Create.

Step 2: Add Secrets

Inside your Key Vault → Go to Secrets → Click “Generate/Import”.

Add secrets such as:

  • DatabaseConnectionString
  • RedisCache

Step 3: Register App with Azure AD

  1. Go to App Registrations → Click “New Registration”.
  2. Save the Client ID.
  3. Go to Certificates & Secrets → Add a new Client Secret.
  4. Save the secret value immediately!

Step 4: Add to appsettings.json

"KeyVaultConfiguration": {
  "KeyVaultURL": "https://yourvaultname.vault.azure.net/",
  "ClientId": "your-client-id",
  "ClientSecret": "your-client-secret"
}

Step 5: Configure in Program.cs

builder.Host.ConfigureAppConfiguration((context, config) =>
{
    var settings = config.Build();
    var keyVaultURL = settings["KeyVaultConfiguration:KeyVaultURL"];
    var clientId = settings["KeyVaultConfiguration:ClientId"];
    var clientSecret = settings["KeyVaultConfiguration:ClientSecret"];

    config.AddAzureKeyVault(keyVaultURL, clientId, clientSecret, new DefaultKeyVaultSecretManager());
});

🧩 Binding Configuration to a Custom Class

Step 1: Define Your Class

public class AppSecrets
{
    public string DatabaseConnectionString { get; set; }
    public string RedisCache { get; set; }
}

Step 2: Register in Program.cs

Option 1: Using IOptions<T> registration

builder.Services.Configure<AppSecrets>(builder.Configuration);

Option 2: Bind manually

var secrets = new AppSecrets();
builder.Configuration.Bind(secrets);

Step 3: Inject with IOptions<AppSecrets>

public class MyService
{
    private readonly AppSecrets _secrets;

    public MyService(IOptions<AppSecrets> options)
    {
        _secrets = options.Value;
    }

    public void PrintSecrets()
    {
        Console.WriteLine(_secrets.DatabaseConnectionString);
    }
}

✅ Benefits

  • Security: Secrets aren’t stored in code or configuration files.
  • Centralized Management: Easy to rotate and audit secrets.
  • Clean Access: Strongly typed classes make your code easier to maintain.
Back to Index
Previous Securing an ASP.NET Core Web API NET Core vs .NET Framework Next
*