ASP.NET Core Custom Configuration Sections Step by step Implementation and Top 10 Questions and Answers
 Last Update: April 01, 2025      18 mins read      Difficulty-Level: beginner

ASP.NET Core Custom Configuration Sections: A Comprehensive Guide

ASP.NET Core offers a robust and flexible configuration system that allows developers to externalize application settings from the code and manage them efficiently. One of the powerful features of this configuration system involves defining and using custom configuration sections to cater to the application's specific needs. In this guide, we will delve deep into custom configuration sections in ASP.NET Core, exploring their importance, implementation, and best practices.

Why Use Custom Configuration Sections?

Before diving into the details of custom configuration sections, it is essential to understand their importance.

  1. Modularity: Custom configuration sections allow for the organization of configuration settings into logical groups, reducing clutter and making the configuration structure more modular and easier to manage.
  2. Reusability: Once defined, custom configuration sections can be reused across different parts of the application, reducing redundancy and ensuring consistency.
  3. Maintainability: Clear and organized configuration settings facilitate easier maintenance, making it simpler to locate and update settings as needed.
  4. Environment-Specific Settings: Custom configuration sections can be tailored to different environments (e.g., Development, Staging, Production) by leveraging built-in ASP.NET Core configuration providers.

Defining Custom Configuration Sections

Let's start with a simple example to illustrate how to define a custom configuration section in ASP.NET Core.

Step 1: Create a Configuration Class

The first step is to create a C# class that represents the structure of the custom configuration section. For instance, if you need to configure settings related to an email service, you might define a class EmailSettings as follows:

public class EmailSettings
{
    public string Host { get; set; }
    public int Port { get; set; }
    public string From { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
}
Step 2: Add Configuration to appsettings.json

Next, add the configuration settings to the appsettings.json file (or any other configuration provider file you are using):

{
  "EmailSettings": {
    "Host": "smtp.example.com",
    "Port": 587,
    "From": "noreply@example.com",
    "Username": "yourusername",
    "Password": "yourpassword"
  }
}
Step 3: Bind Configuration Settings

Bind the custom configuration section to the EmailSettings class in the Startup.cs file or Program.cs file, depending on your project setup. Binding associates the configuration settings with strongly-typed objects, allowing for easier access and manipulation.

For .NET Core 3.0 and later, you can add this binding in the Program.cs file:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                // Existing configuration providers
                config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            })
            .ConfigureServices((context, services) =>
            {
                services.Configure<EmailSettings>(context.Configuration.GetSection("EmailSettings"));
                services.AddControllersWithViews();
            });
}

For older versions like .NET Core 2.x, you can add it in Startup.cs:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
        services.AddControllersWithViews();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // Existing middleware pipeline
    }
}
Step 4: Access Configuration Settings

To access the configuration settings from your classes, you can use the IOptions<T> or IOptionsSnapshot<T> interfaces. Here's an example of how to access EmailSettings in a custom service:

public class EmailService
{
    private readonly EmailSettings _emailSettings;

    public EmailService(IOptions<EmailSettings> emailSettings)
    {
        _emailSettings = emailSettings.Value;
    }

    public void SendEmail(string to, string subject, string body)
    {
        // Use _emailSettings to send an email
        using (var client = new SmtpClient(_emailSettings.Host, _emailSettings.Port))
        {
            client.Credentials = new NetworkCredential(_emailSettings.Username, _emailSettings.Password);
            client.EnableSsl = true;
            using (var message = new MailMessage(_emailSettings.From, to, subject, body))
            {
                client.Send(message);
            }
        }
    }
}

Environment-Specific Configuration

ASP.NET Core allows you to manage environment-specific configuration settings using multiple configuration files. For each environment, you can create a specific configuration file, such as appsettings.Development.json, appsettings.Staging.json, etc. These files override the base configuration settings in appsettings.json for the respective environment.

For example, in appsettings.Development.json:

{
  "EmailSettings": {
    "Host": "localhost",
    "Port": 1025,
    "From": "noreply@development.com",
    "Username": "devuser",
    "Password": "devpass"
  }
}

ASP.NET Core automatically selects the appropriate configuration file based on the ASPNETCORE_ENVIRONMENT environment variable.

Best Practices

  1. Use Environment-Specific Configuration: Leverage environment-specific configuration files to manage different settings for development, staging, and production environments.
  2. Secure Sensitive Information: Use environment variables or external secrets management tools like Azure Key Vault to store sensitive information such as passwords and API keys.
  3. Organize Configuration Settings: Group related configuration settings into logical sections to keep the appsettings.json file manageable and maintainable.
  4. Validate Configuration Settings: Consider adding validation logic to ensure that configuration settings are correct and complete before application startup.
  5. Leverage IOptions Interfaces: Use IOptions<T> or IOptionsSnapshot<T> to access configuration settings in a thread-safe manner, especially in long-lived services.

By following these best practices, you can effectively utilize custom configuration sections in ASP.NET Core to build flexible and maintainable applications.

Conclusion

Custom configuration sections in ASP.NET Core provide developers with the ability to define organized, reusable, and maintainable configuration settings. By structuring configuration data into logical sections and leveraging the built-in configuration system, you can improve the modularity and scalability of your application. Whether you're developing a simple web application or a complex enterprise system, understanding and implementing custom configuration sections is a valuable skill in the ASP.NET Core ecosystem.

With this guide, you now have a comprehensive understanding of how to define, bind, and access custom configuration sections in ASP.NET Core, allowing you to build more robust and adaptable applications.

Examples, Set Route and Run the Application: ASP.NET Core Custom Configuration Sections for Beginners

ASP.NET Core offers a robust and flexible way to manage application configurations. One of the powerful features of ASP.NET Core is the ability to define and use custom configuration sections. This guide will walk you through creating a custom configuration section, setting up routes, and running the application, step-by-step. This will be an excellent exercise for beginners to understand how configurations work in ASP.NET Core.

Step 1: Setting Up the Project

First, you need to create a new ASP.NET Core Web Application. You can use Visual Studio or the .NET CLI to accomplish this. Here’s how you can do it using the .NET CLI:

dotnet new webapi -n CustomConfigDemo
cd CustomConfigDemo

Step 2: Define the Custom Configuration Model

To work with custom configuration sections, you need to define a class that represents your configuration structure.

Create a new class DatabaseSettings.cs in the Models folder:

namespace CustomConfigDemo.Models
{
    public class DatabaseSettings
    {
        public string ConnectionString { get; set; }
        public string DatabaseName { get; set; }
        public bool UseIntegratedSecurity { get; set; }
    }
}

Step 3: Update appsettings.json with Custom Configuration

Next, add your custom configuration section into the appsettings.json file. Here's an example:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "DatabaseSettings": {
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=true",
    "DatabaseName": "MyDatabase",
    "UseIntegratedSecurity": true
  }
}

Step 4: Bind the Configuration Section to the Model

In ASP.NET Core, you can bind custom configuration sections to your model classes using the services.Configure<T> method.

Open Startup.cs or Program.cs (depending on the version of ASP.NET Core you are using) and modify it like this:

using CustomConfigDemo.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        // Bind the custom configuration section to the DatabaseSettings model
        services.Configure<DatabaseSettings>(Configuration.GetSection("DatabaseSettings"));
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

Step 5: Use the Custom Configuration in a Controller

Finally, you can access the configuration data from your controller by injecting an IOptions<T> instance.

Create a new controller called DatabaseController.cs:

using CustomConfigDemo.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

namespace CustomConfigDemo.Controllers
{
    [Route("api/[controller]")]
    public class DatabaseController : ControllerBase
    {
        private readonly DatabaseSettings _databaseSettings;

        public DatabaseController(IOptions<DatabaseSettings> databaseSettings)
        {
            _databaseSettings = databaseSettings.Value;
        }

        [HttpGet]
        public IActionResult Get()
        {
            return Ok(new
            {
                ConnectionString = _databaseSettings.ConnectionString,
                DatabaseName = _databaseSettings.DatabaseName,
                UseIntegratedSecurity = _databaseSettings.UseIntegratedSecurity
            });
        }
    }
}

Step 6: Set Route and Run the Application

Now that everything is set up, you can run the application and test the controller.

Run the application using the following command:

dotnet run

Once the application is running, navigate to http://localhost:5000/api/database (or the appropriate port your application is running on). You should see a JSON response containing the configuration data for your database settings.

{
  "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=true",
  "DatabaseName": "MyDatabase",
  "UseIntegratedSecurity": true
}

Conclusion

In this guide, you’ve learned how to work with custom configuration sections in ASP.NET Core. By following these steps, you created a custom configuration model, updated the appsettings.json file, bound the configuration section to your model, and accessed the configuration data in a controller. This process can be extended to other types of configurations and more complex models, allowing you to manage your application’s settings effectively and maintainably.

Certainly! Here are the Top 10 Questions and Answers about ASP.NET Core Custom Configuration Sections:


1. What are Configuration Sections in ASP.NET Core and why are they important?

Answer: In ASP.NET Core, configuration sections are organizational units within the configuration data that allow you to group settings logically. They help in managing complex configuration settings efficiently and make your configuration files more readable and maintainable.

Importance:

  • Clarity: Organizes settings logically, making the configuration file easier to understand.
  • Maintainability: Easier to update and modify specific settings without affecting others.
  • Reusability: Facilitates the reuse of settings across different parts of the application or even different projects.

2. How can I create and use a custom configuration section in ASP.NET Core?

Answer: Creating a custom configuration section involves defining a class that represents your configuration structure and then binding this class to the configuration data in your application.

Steps:

  1. Define the Configuration Class:

    public class MyCustomConfig
    {
        public string Setting1 { get; set; }
        public int Setting2 { get; set; }
        public List<string> Setting3 { get; set; }
    }
    
  2. Add Configuration Data: In your appsettings.json, add a section like:

    {
      "MyCustomConfig": {
        "Setting1": "Value1",
        "Setting2": 42,
        "Setting3": ["Item1", "Item2", "Item3"]
      }
    }
    
  3. Bind Configuration to the Class: In Startup.cs or Program.cs (depending on your ASP.NET Core version), configure services to bind the section:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<MyCustomConfig>(Configuration.GetSection("MyCustomConfig"));
        services.AddControllersWithViews();
    }
    
  4. Access Configuration in Controllers or Services: Inject IOptions<T> and use it to access the settings:

    public class HomeController : Controller
    {
        private readonly MyCustomConfig _myCustomConfig;
    
        public HomeController(IOptions<MyCustomConfig> myCustomConfig)
        {
            _myCustomConfig = myCustomConfig.Value;
        }
    
        public IActionResult Index()
        {
            ViewBag.Setting1 = _myCustomConfig.Setting1;
            return View();
        }
    }
    

3. Can I have nested custom configuration sections?

Answer: Yes, ASP.NET Core supports nested custom configuration sections, allowing you to define configurations in a more structured and detailed manner.

Example:

public class MyCustomConfig
{
    public string Setting1 { get; set; }
    public NestedSettings Nested { get; set; }
}

public class NestedSettings
{
    public string SubSetting1 { get; set; }
    public int SubSetting2 { get; set; }
}

Configuration in appsettings.json:

{
  "MyCustomConfig": {
    "Setting1": "Value1",
    "Nested": {
      "SubSetting1": "SubValue1",
      "SubSetting2": 100
    }
  }
}

4. Is it possible to read configuration from different sources besides appsettings.json?

Answer: Yes, ASP.NET Core supports reading configuration from various sources, including environment variables, command-line arguments, user secrets, Azure Key Vault, and more.

Configuration Sources:

  • appsettings.json and appsettings.{Environment}.json (e.g., appsettings.Development.json)
  • Environment Variables
  • Command-Line Arguments
  • User Secrets
  • Azure Key Vault
  • Custom Providers

Example: Adding Multiple Configuration Sources:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                      .AddEnvironmentVariables()
                      .AddCommandLine(args);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

5. How do I reload configuration when it changes in ASP.NET Core?

Answer: ASP.NET Core allows you to reload configuration settings when the underlying data source changes. This is particularly useful for settings that might change without restarting the application.

Steps:

  1. Enable Reload on Change: When adding the JSON configuration source, set reloadOnChange to true:

    config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    
  2. Use IOptionsSnapshot or IOptionsMonitor: To read the latest configuration values:

    public class HomeController : Controller
    {
        private readonly IOptionsSnapshot<MyCustomConfig> _myCustomConfigSnapshot;
    
        public HomeController(IOptionsSnapshot<MyCustomConfig> myCustomConfigSnapshot)
        {
            _myCustomConfigSnapshot = myCustomConfigSnapshot;
        }
    
        public IActionResult Index()
        {
            var config = _myCustomConfigSnapshot.Value;
            ViewBag.Setting1 = config.Setting1;
            return View();
        }
    }
    

    Alternatively, you can use IOptionsMonitor for even more flexibility, particularly if you need to react to changes programmatically.

6. How can I validate custom configuration sections in ASP.NET Core?

Answer: Validating custom configuration settings ensures that the application receives the correct and expected data, preventing runtime errors.

Approaches:

  1. Data Annotations: Use data annotations to define validation rules on the configuration class.

    using System.ComponentModel.DataAnnotations;
    
    public class MyCustomConfig
    {
        [Required]
        public string Setting1 { get; set; }
    
        [Range(1, 100)]
        public int Setting2 { get; set; }
    }
    
  2. Model Validation: Validate the configuration object manually using Validator:

    public void ConfigureServices(IServiceCollection services)
    {
        var config = services.BuildServiceProvider()
                              .GetRequiredService<IConfiguration>()
                              .GetSection("MyCustomConfig")
                              .Get<MyCustomConfig>();
    
        var validationResults = new List<ValidationResult>();
        var isValid = Validator.TryValidateObject(config, new ValidationContext(config), validationResults, true);
        if (!isValid)
        {
            foreach (var validationResult in validationResults)
            {
                throw new InvalidOperationException(validationResult.ErrorMessage);
            }
        }
    
        services.Configure<MyCustomConfig>(Configuration.GetSection("MyCustomConfig"));
        services.AddControllersWithViews();
    }
    
  3. Custom Validation: Implement custom validation logic if the built-in options are not sufficient.

7. Can I provide default values for custom configuration settings in ASP.NET Core?

Answer: Yes, you can provide default values for configuration settings using the IOptions and IOptions<T> pattern or by setting default values in the configuration class itself.

Approaches:

  1. Default Values in Class:

    public class MyCustomConfig
    {
        public string Setting1 { get; set; } = "DefaultValue";
        public int Setting2 { get; set; } = 42;
    }
    
  2. Use OptionsBuilder to Set Defaults:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<MyCustomConfig>(options =>
        {
            options.Setting1 = "DefaultValue";
            options.Setting2 = 42;
        });
    
        services.Configure<MyCustomConfig>(Configuration.GetSection("MyCustomConfig"));
        services.AddControllersWithViews();
    }
    
  3. Default Values in appsettings.json: Ensure that default values are specified in the appsettings.json file.

8. How can I access configuration outside of services in ASP.NET Core?

Answer: While dependency injection (IOptions<T>) is the preferred way to access configuration within services, there are methods to access configuration outside of the service container.

Approaches:

  1. Use IConfiguration Directly: Inject IConfiguration wherever needed:

    public class MyClass
    {
        private readonly IConfiguration _configuration;
    
        public MyClass(IConfiguration configuration)
        {
            _configuration = configuration;
        }
    
        public void DoWork()
        {
            var setting1 = _configuration.GetValue<string>("MyCustomConfig:Setting1");
        }
    }
    
  2. Singleton Access: Register IConfiguration as a singleton and access it globally (not recommended for most cases due to tight coupling).

  3. Configuration Builder: Use the configuration builder to access configuration statically:

    var config = new ConfigurationBuilder()
                   .SetBasePath(Directory.GetCurrentDirectory())
                   .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                   .Build();
    
    var setting1 = config.GetValue<string>("MyCustomConfig:Setting1");
    

9. How do I securely manage sensitive configuration data in ASP.NET Core?

Answer: Sensitive data such as API keys, passwords, and other secrets should not be hard-coded in source files. ASP.NET Core provides several mechanisms to manage sensitive data securely.

Approaches:

  1. Environment Variables: Store sensitive data in environment variables and access them in the application.

    config.AddEnvironmentVariables(prefix: "MyApp_");
    
  2. User Secrets: Use user secrets for development environments to store secrets outside the source code.

    • Install the Secrets tool and add a secret:
      dotnet user-secrets init
      dotnet user-secrets set "MyCustomConfig:SecretSetting" "SensitiveValue"
      
    • Configure in Program.cs:
      if (env.IsDevelopment())
      {
          config.AddUserSecrets<Program>();
      }
      
  3. Azure Key Vault: For production environments, use Azure Key Vault to manage secrets.

    config.AddAzureKeyVault(
        new SecretClient(new Uri($"https://{vaultName}.vault.azure.net/"), new DefaultAzureCredential()));
    
  4. Protected Configuration: Use encrypted sections in web.config (applicable to .NET Framework, not directly in ASP.NET Core, but can be integrated).

10. What are some best practices for working with custom configuration sections in ASP.NET Core?

Answer: Following best practices helps ensure that your configuration management is efficient, secure, and maintainable.

Best Practices:

  1. Use Strongly-Typed Configuration: Define configuration classes to avoid magic strings and leverage type safety.

    services.Configure<MyCustomConfig>(Configuration.GetSection("MyCustomConfig"));
    
  2. Separate Environment-Specific Settings: Use environment-specific configuration files (e.g., appsettings.Development.json, appsettings.Production.json) to override settings based on the environment.

  3. Validate Configuration: Implement validation to ensure that configuration settings meet the expected criteria.

  4. Secure Sensitive Data: Use environment variables, user secrets, or Azure Key Vault to manage sensitive information.

  5. Optimize Reloads: Only enable reloading for configurations that need it to improve performance.

  6. Document Configuration Settings: Provide documentation or comments to explain the purpose and usage of each configuration setting.

  7. Use IOptions<T> for Dependency Injection: Leverage the built-in options pattern to inject configuration into services via dependency injection.

  8. Test Configuration: Write unit and integration tests to ensure that configuration is read and applied correctly.


By adhering to these practices and understanding how to work with custom configuration sections in ASP.NET Core, you can build more robust, maintainable, and secure applications.