How to create a custom configuration provider in ASP.NET Core 6

We use configuration providers in ASP.NET Core to load configuration data into our application from one or more configuration sources. These providers can read configuration data from command line arguments, environment variables, JSON or XML files, databases, Azure Key Vault, and other sources, including your own custom sources.

The ASP.NET Core configuration system includes a set of classes that make it easy to manage your application’s configuration settings. This system is lightweight and extensible, and it provides a consistent way to store and retrieve configuration settings for all ASP.NET Core applications.

For custom configuration sources, you can create your own custom configuration provider in ASP.NET Core and attach it to the configuration system. A custom configuration provider can help reduce the complexity of loading configuration metadata from custom configuration sources or external sources.

This article presents a discussion on how we can create a custom configuration provider in ASP.NET Core 6. To work with the code samples provided in this article, you must have Visual Studio 2022 installed on your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

Create an ASP.NET Core 6 Web API project in Visual Studio 2022

First, let’s create an ASP.NET Core project in Visual Studio 2022. Follow these steps to create a new ASP.NET Core 6 Web API project in Visual Studio 2022:

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create a new project”.
  3. In the “Create a new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location of the new project.
  6. Optionally check the box “Place the solution and the project in the same directory”, according to your preferences.
  7. Click Next.
  8. In the “Additional Information” window displayed below, select .NET 6.0 as the target framework from the drop-down list at the top. Leave the “Authentication type” set to “None” (default).
  9. Make sure the “Enable Docker”, “Configure for HTTPS”, and “Enable Open API Support” checkboxes are unchecked as we won’t be using any of these features here.
  10. Click Create.

We’ll use this ASP.NET Core 6 Web API project to create a custom configuration provider in later sections of this article.

Creating configuration providers in ASP.NET Core 6

A configuration provider is typically a C# class that can retrieve configuration data from a source (a file, database, external API, etc.) and make it available to the application. There are many configuration providers built into ASP.NET Core, including JSON, XML, and database providers. However, you can also create your custom configuration provider if needed.

To create a custom configuration provider, you must create a class that extends the ConfigurationProvider class. Then you need to override the Load() method to load the configuration data from where it is stored and return the data as a key-value dictionary.

Once you’ve created your custom configuration provider, you can register it with ASP.NET Core by adding it to the services collection in the Program.cs file.

custom config provider 01 IDG

Figure 1. The Solution Explorer window of the completed application.

Now let’s start creating a custom configuration provider in ASP.NET 6 Core. The final solution will include the following files:

  • SecurityMetadata.cs
  • CustomConfigurationSource.csCustomConfigurationSource.cs
  • CustomConfigurationProvider.csCustomConfigurationProvider.cs
  • CustomConfigurationExtensions.cs
  • CustomConfigurationController.cs

We’ll learn more about each of these files in the sections that follow. Additionally, we will also write code in the Program.cs file to add the configuration provider and configuration source to the default ASP.NET Core runtime configuration system. The finished application’s Solution Explorer window should appear as shown in Figure 1 above.

Create a class for security metadata in ASP.NET Core 6

We’ll store API keys and API secrets in a .json file and read it into the application we’ll build here. We won’t use any of these keys to authenticate or authorize requests in this example.

Both API keys and API secrets are used to authenticate access to an API. The main difference is that API keys are public and available to everyone, while API secrets are private and should never be shared. An API key is an identifier that allows you to interact with an API in a secure way.

API keys are used to restrict who can use an application and what they can do with it; that is, they are used to authenticate and authorize requests. API secrets are used to store sensitive information in your application. You can also use API secrets to generate checksums and to encrypt and decrypt data.

Create a class named SecurityMetadata in a file of the same name with a .cs extension and enter the following code.

   public class SecurityMetadata
    {
        public string ApiKey { get; set; }        
        public string ApiSecret { get; set; }
    }

Create a class for a configuration source in ASP.NET Core 6

Next, we’ll create a configuration source to initialize our custom configuration provider. To do this, create a new .cs file named CustomConfigurationSource and give it the following code.

    public class CustomConfigurationSource : IConfigurationSource
    {
        public IConfigurationProvider Build(IConfigurationBuilder builder)
        {
            return new CustomConfigurationProvider();
        }
    }

Your custom configuration source must implement the IConfigurationSource interface. The IConfigurationSource interface contains the Build method where you should call your custom configuration provider.

Create a custom configuration provider in ASP.NET Core 6

To read configuration information from an external data source, you must implement your custom configuration provider. Your custom configuration provider is a normal C# class that extends the Microsoft.Extensions.Configuration.ConfigurationProvider abstract class and overrides the Load() method as shown in the code listing below.

    public class CustomConfigurationProvider :
    Microsoft.Extensions.Configuration.ConfigurationProvider
    {
        public override void Load()
        {
            var text = File.ReadAllText(@"D:SecurityMetadata.json");
            var options = new JsonSerializerOptions
            { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
            var content = JsonSerializer.Deserialize
           (text, options);
            if (content != null)
            {
                Data = new Dictionary
                {
                    {"ApiKey", content.ApiKey},
                    {"ApiSecret", content.ApiSecret}
                };
            }
        }
    }

Note how ApiKey and ApiSecret are stored in the dictionary instance named Data.

Create a custom configuration extension class in ASP.NET Core 6

We will now create an extension method that will create an instance of the CustomConfigurationSource class and return it.

    public static class CustomConfigurationExtensions
    {
        public static IConfigurationBuilder AddSecurityConfiguration
        (this IConfigurationBuilder builder)
        {
            return builder.Add(new CustomConfigurationSource());
        }
    }

Add Custom Config Source to Program.cs in ASP.NET Core 6

Now enter the following line of code in the Program.cs file to add the custom configuration source to the configuration provider collection.

builder.Configuration.AddSecurityConfiguration();

The complete code list of Program.cs file is given below for your reference.

using CustomConfigurationProvider;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Configuration.AddSecurityConfiguration();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();

Create a custom configuration controller in ASP.NET Core 6

Finally, create a new API controller named CustomConfigurationController and replace the default generated code with the following code list.

    [Route("api/[controller]")]
    [ApiController]
    public class CustomConfigurationController : ControllerBase
    {
        private readonly IConfiguration _configuration;
        public CustomConfigurationController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        [HttpGet]
        public IActionResult Get()
        {
            var metadata = new SecurityMetadata
            {
                ApiKey = _configuration["ApiKey"],
                ApiSecret = _configuration["ApiSecret"]
            };
            return Ok(metadata);
        }
    }

Note how the IConfiguration instance is injected into the constructor of the CustomConfigurationController class.

If you now run the app and hit the HttpGet endpoint of the CustomConfigurationController, you should see configuration data returned after reading it from the .json file in the filesystem. To verify this, set a breakpoint in the HttpGet action method of the CustomConfigurationController, as shown in Figure 2 below.

custom configuration provider 02 IDG

Figure 2. ApiKey and ApiSecret are returned by the HttpGet action method.

In this article, we implemented a custom configuration provider that can read configuration data from a .json file. Note that we ran the application directly from the Visual Studio 2022 IDE and set a breakpoint to check if the configuration data is returned correctly. You can also run the app using Postman, Fiddler, or the Swagger UI.

Copyright © 2022 IDG Communications, Inc.

Comments are closed.