App configuration
Tip
This content is an excerpt from the eBook, Blazor for ASP NET Web Forms Developers for Azure, available on .NET Docs or as a free downloadable PDF that can be read offline.
The primary way to load app configuration in Web Forms is with entries in the web.config file—either on the server or a related configuration file referenced by web.config. You can use the static ConfigurationManager
object to interact with app settings, data repository connection strings, and other extended configuration providers that are added into the app. It's typical to see interactions with app configuration as seen in the following code:
var configurationValue = ConfigurationManager.AppSettings["ConfigurationSettingName"];
var connectionString = ConfigurationManager.ConnectionStrings["MyDatabaseConnectionName"].ConnectionString;
With ASP.NET Core and server-side Blazor, the web.config file MAY be present if your app is hosted on a Windows IIS server. However, there's no ConfigurationManager
interaction with this configuration, and you can receive more structured app configuration from other sources. Let's take a look at how configuration is gathered and how you can still access configuration information from a web.config file.
Configuration sources
ASP.NET Core recognizes there are many configuration sources you may want to use for your app. The framework attempts to offer you the best of these features by default. Configuration is read and aggregated from these various sources by ASP.NET Core. Later loaded values for the same configuration key take precedence over earlier values.
ASP.NET Core was designed to be cloud-aware and to make the configuration of apps easier for both operators and developers. ASP.NET Core is environment-aware and knows if it's running in your Production
or Development
environment. The environment indicator is set in the ASPNETCORE_ENVIRONMENT
system environment variable. If no value is configured, the app defaults to running in the Production
environment.
Your app can trigger and add configuration from several sources based on the environment's name. By default, the configuration is loaded from the following resources in the order listed:
- appsettings.json file, if present
- appsettings.{ENVIRONMENT_NAME}.json file, if present
- User secrets file on disk, if present
- Environment variables
- Command-line arguments
appsettings.json format and access
The appsettings.json file can be hierarchical with values structured like the following JSON:
{
"section0": {
"key0": "value",
"key1": "value"
},
"section1": {
"key0": "value",
"key1": "value"
}
}
When presented with the preceding JSON, the configuration system flattens child values and references their fully qualified hierarchical paths. A colon (:
) character separates each property in the hierarchy. For example, the configuration key section1:key0
accesses the section1
object literal's key0
value.
User secrets
User secrets are:
- Configuration values that are stored in a JSON file on the developer's workstation, outside of the app development folder.
- Only loaded when running in the
Development
environment. - Associated with a specific app.
- Managed with the .NET CLI's
user-secrets
command.
Configure your app for secrets storage by executing the user-secrets
command:
dotnet user-secrets init
The preceding command adds a UserSecretsId
element to the project file. The element contains a GUID, which is used to associate secrets with the app. You can then define a secret with the set
command. For example:
dotnet user-secrets set "Parent:ApiKey" "12345"
The preceding command makes the Parent:ApiKey
configuration key available on a developer's workstation with the value 12345
.
For more information about creating, storing, and managing user secrets, see the Safe storage of app secrets in development in ASP.NET Core document.
Environment variables
The next set of values loaded into your app configuration is the system's environment variables. All of your system's environment variable settings are now accessible to you through the configuration API. Hierarchical values are flattened and separated by colon characters when read inside your app. However, some operating systems don't allow the colon character environment variable names. ASP.NET Core addresses this limitation by converting values that have double-underscores (__
) into a colon when they're accessed. The Parent:ApiKey
value from the user secrets section above can be overridden with the environment variable Parent__ApiKey
.
Command-line arguments
Configuration can also be provided as command-line arguments when your app is started. Use the double-dash (--
) or forward-slash (/
) notation to indicate the name of the configuration value to set and the value to be configured. The syntax resembles the following commands:
dotnet run CommandLineKey1=value1 --CommandLineKey2=value2 /CommandLineKey3=value3
dotnet run --CommandLineKey1 value1 /CommandLineKey2 value2
dotnet run Parent:ApiKey=67890
The return of web.config
If you've deployed your app to Windows on IIS, the web.config file still configures IIS to manage your app. By default, IIS adds a reference to the ASP.NET Core Module (ANCM). ANCM is a native IIS module that hosts your app in place of the Kestrel web server. This web.config section resembles the following XML markup:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\MyApp.exe"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
App-specific configuration can be defined by nesting an environmentVariables
element in the aspNetCore
element. The values defined in this section are presented to the ASP.NET Core app as environment variables. The environment variables load appropriately during that segment of app startup.
<aspNetCore processPath="dotnet"
arguments=".\MyApp.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
<environmentVariable name="Parent:ApiKey" value="67890" />
</environmentVariables>
</aspNetCore>
Read configuration in the app
ASP.NET Core provides app configuration through the IConfiguration interface. This configuration interface should be requested by your Blazor components, Blazor pages, and any other ASP.NET Core-managed class that needs access to configuration. The ASP.NET Core framework will automatically populate this interface with the resolved configuration configured earlier. On a Blazor page or a component's Razor markup, you can inject the IConfiguration
object with an @inject
directive at the top of the .razor file like this:
@inject IConfiguration Configuration
This preceding statement makes the IConfiguration
object available as the Configuration
variable throughout the rest of the Razor template.
Individual configuration settings can be read by specifying the configuration setting hierarchy sought as an indexer parameter:
var mySetting = Configuration["section1:key0"];
You can fetch entire configuration sections by using the GetSection method to retrieve a collection of keys at a specific location with a syntax similar to GetSection("section1")
to retrieve the configuration for section1 from the earlier example.
Strongly typed configuration
With Web Forms, it was possible to create a strongly typed configuration type that inherited from the ConfigurationSection type and associated types. A ConfigurationSection
allowed you to configure some business rules and processing for those configuration values.
In ASP.NET Core, you can specify a class hierarchy that will receive the configuration values. These classes:
- Don't need to inherit from a parent class.
- Should include
public
properties that match the properties and type references for the configuration structure you wish to capture.
For the earlier appsettings.json sample, you could define the following classes to capture the values:
public class MyConfig
{
public MyConfigSection section0 { get; set;}
public MyConfigSection section1 { get; set;}
}
public class MyConfigSection
{
public string key0 { get; set; }
public string key1 { get; set; }
}
This class hierarchy can be populated by adding the following line to the Startup.ConfigureServices
method (or appropriate location in Program.cs using the builder.Services
property instead of services
):
services.Configure<MyConfig>(Configuration);
In the rest of the app, you can add an input parameter to classes or an @inject
directive in Razor templates of type IOptions<MyConfig>
to receive the strongly typed configuration settings. The IOptions<MyConfig>.Value
property will yield the MyConfig
value populated from the configuration settings.
@inject IOptions<MyConfig> options
@code {
var MyConfiguration = options.Value;
var theSetting = MyConfiguration.section1.key0;
}
More information about the Options feature can be found in the Options pattern in ASP.NET Core document.