Advanced Basics: Using Transforms In Your ASP.NET Project, Part 2

August 21st, 2019

In part 2, we cover how ASP.NET Core uses configuration files through appsettings.json files and environment settings

In the last post, we discuss how configuration files are important in your ASP.NET projects and how they can help other teams in knowing what parameters to use in your application.

In this final post, I discuss the different settings in an ASP.NET Core web application instead.

What about AppSettings in ASP.NET Core?

With the latest ASP.NET Core, things have changed...a little.

While there isn't a ConfigurationManager any more, configuration settings are used through appsettings.json files now. Instead of XML, we are now using JSON. I hear JSON is an up-and-coming thing, dontcha know? ;-)

They function the same way, but instead of a XML Transform, your JSON configuration files will replace the properties in the same hierarchy.

For example, in the appsettings.json file, 

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Your appsettings.development.json file looks like this:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

However, transforms don't occur with the MSBuild.exe. They occur in code.

Startup.cs is where everything takes place for your ASP.NET Core application. A default Startup method in the Startup.cs looks like this:

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

To introduce specific appsettings to your application, modify your Startup method to look like this:

public Startup(IConfiguration configuration, IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(AppContext.BaseDirectory)
        .AddJsonFile("appsettings.json", false, true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables();
 
    Configuration = builder.Build();
}

If you notice, we added an IHostingEnvironment parameter. Why? Because dependency injection. We automatically get the IHostingEnvironment injected because it contains the environment variable for the project...and we need it.

After we set the BasePath, we add a "base" JSON file called appsettings.json. Anything after the appsettings.json line will be applied by adding or overwriting a name/value pair in subsequent .json files.

Using the example above, the "LogLevel.Default" will be replaced with "Debug" when we use the Development settings.

Changing the Environment Variable

The setting you want to change are located in your project's profile.

Right-click on the project and select Properties. Click on Debug to find the ASPNETCORE_ENVIRONMENT variable.

Each profile can contain your ASPNETCORE_ENVIRONMENT variable. These can be custom to however you want to setup your environments.

As mentioned in the docs, there are extension methods to assist with your configuration in the Startup method.

That covers the different environments in code.

But what about DevOps?

I can hear the DevOps people screaming, "But I don't have control over the different environments when building the project."

Yes, you do.

With the "dotnet build", you can specify the configuration for the build. If I wanted to run the Debug version to build my project in my DevOps Pipeline, the command line would look like this:

dotnet build --configuration Debug

As with Visual Studio, you can also add custom environments. The following dotnet build command line create a QA version of the build as well.

dotnet build --configuration QA

There are many options for performing a build on a different server with various configurations.

While I've touched on a few ways to use ASPNETCORE_ENVIRONMENT variables, I also wanted to mention Andrew Locke's awesome post about How to Set The Hosting Environment in ASP.NET Core.

Conclusion

Configuration files are especially important to centralize the settings for your application and especially important as to what environment your application is pointing to.

There was a time when a new dev performed a transform, checked code in, automatically deployed, and Voila!...our project on QA was pointing to a production server. He got confused when all of the configuration settings were in one large file.

As you can see, having them in separate environment files is absolutely helpful in the long run.

I hope these two posts provided enough evidence as to why configuration files are important in ASP.NET and ASP.NET Core.

Do you use configuration files? How do you DevOps ASP.NET Core projects? Post your comments below and let's discuss.