Merging web.config with Azure App Configuration
Tags: azureappconfiguration, dotnet, netframework
Published: 2022-03-30 20:37:22

---
title: Merging web.config with Azure App Configuration
published: true
description: How to use merge legacy web.config settings with modern configuration from Azure App Configuration
tags: azureappconfiguration,dotnet,netframework
//cover_image: https://direct_url_to_image.jpg
---

If you're working in the Azure space, you will probably know that Azure App Configuration is the new hotness. It allows for powerful, centralised control of the application configuration making managing local config files redundant.

However with new hotness often comes the lack of backwards compatibility. Thankfully, Microsoft haven't completely forgotten about those who still have to work with .Net Framework projects.

I won't go into *how* to set up Azure App Configuration with .Net Framework because it is already [well documented by Microsoft](https://docs.microsoft.com/en-us/azure/azure-app-configuration/enable-dynamic-configuration-aspnet-netfx).

However, what I am going to describe is a method of merging legacy config values from your web.config files with config values from Azure App Configuration into a single DI-friendly *IConfiguration* class.

##The goodies

```
var builder = new Microsoft.Extensions.Configuration.ConfigurationBuilder();
builder.AddInMemoryCollection(ConfigurationManager.AppSettings.ToDictionary());
builder.AddAzureAppConfiguration(options =>
{
    options.Connect(aacConnectionString)
        .Select(KeyFilter.Any, LabelFilter.Null)
        .ConfigureRefresh(refresh =>
        {
            refresh.Register("TestApp:Sentinel", refreshAll: true)
                    .SetCacheExpiration(new TimeSpan(0, 5, 0));
        });
    _configurationRefresher = options.GetRefresher();
});

_configuration = builder.Build();

protected void Application_BeginRequest(object sender, EventArgs e)
{
    bool result = _configurationRefresher.TryRefreshAsync().GetAwaiter().GetResult();
}
```

This is largely boileplate code from the link provided above with the addition of

```
builder.AddInMemoryCollection(ConfigurationManager.AppSettings.ToDictionary())
```

The key here is the extension method which does the conversion

```
public static IDictionary<string, string> ToDictionary(this NameValueCollection collection)
{
    var dictionary = collection.Cast<string>().ToDictionary(k => k, v => collection[v]);

    return dictionary;
}
```

Under the hood, if you inspect the IConfiguration that the builder produces, you will see two providers - InMemoryProvider and AzureAppConfigurationProvider. Thankfully you don't need to specify which provider when retrieving the key value. They can simply be referred to by 
```
configuration["keyname"]
```

NOTE: config keys that exist in both web.config and Azure App Configuration will be taken as "last wins".

##Additional hotness

If you are conscious of security, you will probably not be committing secrets like connection strings to your source control. However you need these when developing code, so you store them in an gitignore'd file and reference it like so:

```
<appSettings file="appsettings.dev.config">
```

The good news is this is totally supported because the ConfigurationManager works out all this stuff before the Application_Start method is triggered.

##Credit
This work was inspired by this blog post which pointed the way to .AddInMemoryCollection(...)

[Azure App Configuration – Getting the connection string from appsettings.json](https://briancaos.wordpress.com/2020/02/14/azure-app-configuration-getting-the-connection-string-from-appsettings-json/)