Debug ASP.NET Core application configuration

 
 
  • Gérald Barré

Configuration in ASP.NET Core is performed using one or more configuration providers. Configuration providers read configuration data from key-value pairs using a variety of configuration sources such as the appsettings.json file, environment variables, vaults and so on. All these sources are merged into one IConfiguration object. To debug the content of the IConfiguration instance, you can use the GetDebugView extension method. This method outputs the name, value and source of each configuration entry.

One way to expose this information is by creating a new route in your application. Be careful to not expose this route in production. Indeed, the configuration may contain sensitive information such as secrets…

C#
public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration) => Configuration = configuration;

    public void ConfigureServices(IServiceCollection services) => services.AddControllers();

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            // 👇 Be sure to not publish this route in production as it may disclose some secrets
            if (env.IsDevelopment())
            {
                endpoints.MapGet("debug/configuration", async request =>
                {
                    var config = ((IConfigurationRoot)Configuration).GetDebugView();
                    await request.Response.WriteAsync(config, request.RequestAborted);
                });
            }

            endpoints.MapControllers();
        });
    }
}

You can now access open this url in your browser to view the content of the configuration:

note: This post is inspired from the Cecil L. Phillip's tweet

#Customize the output

You can implement the debug view yourself by iterating on configuration sections and providers.

C#
public static string GetCustomDebugView(IConfigurationRoot root)
{
    var builder = new StringBuilder();
    RecurseChildren(builder, root.GetChildren());
    return builder.ToString();

    void RecurseChildren(StringBuilder stringBuilder, IEnumerable<IConfigurationSection> sections)
    {
        foreach (IConfigurationSection section in sections)
        {
            if (section.Value != null)
            {
                var provider = GetProvider(root, section.Path);
                stringBuilder
                    .Append(section.Path)
                    .Append('=')
                    .Append(section.Value)
                    .Append(" (")
                    .Append(provider)
                    .Append(')')
                    .AppendLine();
            }

            RecurseChildren(stringBuilder, section.GetChildren());
        }
    }
}

private static IConfigurationProvider GetProvider(IConfigurationRoot root, string key)
{
    foreach (IConfigurationProvider provider in root.Providers.Reverse())
    {
        if (provider.TryGet(key, out _))
            return provider;
    }

    return null;
}

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub