How to set Environment Name (IHostingEnvironment.EnvironmentName)?

Default ASP.NET Core web project contain such lines in Startup.cs:

if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase))
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage(ErrorPageOptions.ShowAll);
}
else
{
app.UseExceptionHandler("/Home/Error");
}

As I understand, the EnvironmentName is a new way to handle Dev/Production environment. But it doesn't changes on Release build configuration. So what is the way to set a different EnvironmentName?

I can imagine that it should be set in "Commands" as a parameter for server.

69694 次浏览

You set the environment by defining an environment variable named ASPNET_ENV. For example, if you want Release SET ASPNET_ENV=Release.

It might also work if you pass ASPNET_ENV=Release as parameter to the commands but I cannot check it now.

Here is how it is implemented: https://github.com/aspnet/Hosting/blob/217f9ca3d3ccf59ea06e6555820974ba9c3b5932/src/Microsoft.AspNet.Hosting/ConfigureHostingEnvironment.cs

If you are thinking that from where it takes this value then as this moment it is static and default value is development.

https://github.com/aspnet/Hosting/blob/dev/src/Microsoft.AspNet.Hosting/HostingEnvironment.cs

When you look at IHostingEnviroment variable type then it is Microsoft.AspNet.Hosting.HostingEnvrioment.

There are two ways you can now change as per dynamic configuration.

  1. You can implement IHostingEnvironment interface and use your own type for that. You can read value from Config file.

  2. You can use interface You can update that variable directly over here.

    public Startup(IHostingEnvironment env)
    {
    // Setup configuration sources.
    Configuration = new Configuration()
    .AddJsonFile("config.json").AddEnvironmentVariables();
    
    
    Configuration.Set("ASPNET_ENV","Your own value");
    }
    

    If you look at services in ConfigureServices there is list of service configure by default and one of them is IConfigureHostingEnviroment. Default implementation is internal class so you can not directly access but you can set above key ASPNET_ENV and it read that value.

https://github.com/aspnet/Hosting/blob/dev/src/Microsoft.AspNet.Hosting/ConfigureHostingEnvironment.cs

After RC2

So what is the way to set a different EnvironmentName?

Set the ASPNETCORE_ENVIRONMENT environmental variable.

There are many ways to set that environmental variable. These include a launchSettings.json profile and other environment-specific ways. Here are some examples.

From a console:

// PowerShell
> $env:ASPNETCORE_ENVIRONMENT="Development"


// Windows Command Line
> SET ASPNETCORE_ENVIRONMENT=Development


// Bash
> ASPNETCORE_ENVIRONMENT=Development

From an Azure Web App's App settings:

Set Environment Name in Azure

Before RC2

I can imagine that it should be set in "Commands" as a parameter for server.

That is true. In your project.json, add --ASPNET_ENV production as a parameter for the server.

"commands": {
"web": "Microsoft.AspNet.Hosting --ASPNET_ENV production --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5001"
}

Now when you run dnx . web from the command line, ASPNET_ENV will be production.

Relevant ASP.NET Core Hosting Source Code

The WebHostBuilder combines "ASPNETCORE_" with the WebHostDefaults.EnvironmentKey to make "ASPNETCORE_environment". It also supports the legacy keys.

WebHostDefaults.cs

namespace Microsoft.AspNetCore.Hosting
{
public static class WebHostDefaults
{
public static readonly string ApplicationKey = "applicationName";
public static readonly string StartupAssemblyKey = "startupAssembly";


public static readonly string DetailedErrorsKey = "detailedErrors";
public static readonly string EnvironmentKey = "environment";
public static readonly string WebRootKey = "webroot";
public static readonly string CaptureStartupErrorsKey = "captureStartupErrors";
public static readonly string ServerUrlsKey = "urls";
public static readonly string ContentRootKey = "contentRoot";
}
}

WebHostBuilder.cs

_config = new ConfigurationBuilder()
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.Build();


if (string.IsNullOrEmpty(GetSetting(WebHostDefaults.EnvironmentKey)))
{
// Try adding legacy environment keys, never remove these.
UseSetting(WebHostDefaults.EnvironmentKey,
Environment.GetEnvironmentVariable("Hosting:Environment")
?? Environment.GetEnvironmentVariable("ASPNET_ENV"));
}

Backward Compatibility

The environment key is set with the ASPNETCORE_ENVIRONMENT environment variable. ASPNET_ENV and Hosting:Environment are still supported, but generate a deprecated message warning.

https://docs.asp.net/en/latest/migration/rc1-to-rtm.html

Default Value

The default value is "Production" and is set here.

  1. On Azure just set ASPNET_ENV environment variable on web app configuration page.

  2. With your own IIS or other hosting providers - modify web.config to include arguments for "web" command:

    <configuration>
    <system.webServer>
    <handlers>
    <add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
    </handlers>
    <httpPlatform processPath="..\approot\web.cmd" arguments="--ASPNET_ENV Development" stdoutLogEnabled="false" stdoutLogFile="..\logs\stdout.log" startupTimeLimit="3600"></httpPlatform>
    </system.webServer>
    </configuration>
    
  3. During development (if you can modify source code), you can also create file named Microsoft.AspNet.Hosting.json in a root of your project and set the ASPNET_ENV variable.

    { "ASPNET_ENV": "Test" }

if you need to set this without changing code - from the command prompt at the root of the project source folder type:

set ASPNET_ENV=Debug

In ASP.NET Core RC2 the variable name is has been changed to ASPNETCORE_ENVIRONMENT

e.g. In Windows you can execute this command on the staging server (with admin rights)

SETX ASPNETCORE_ENVIRONMENT "Staging" /M

This only has be be executed once and after that, the server will always be considered as the staging server.

When you do a dotnet run in the command prompt on that server you will see Hosting environment: Staging

launchsettings.json

At Properties > launchsettings.json

Just like this:

    {
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1032/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
},
"WebAppNetCore": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"web": {
"commandName": "web",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

In VsCode add the following to launch.json

{
"version": "0.2.0",
"configurations": [
{
...
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
...
]
}

I had same problem. To to be independet to enviroment variable and web.config, I created a .json file as (I called it envsettings.json):

{
// Possible string values reported below.
// - Production
// - Staging
// - Development
"ASPNETCORE_ENVIRONMENT": "Staging"
}

Then in Program.cs I added:

public class Program
{
public static void Main(string[] args)
{
var currentDirectoryPath = Directory.GetCurrentDirectory();
var envSettingsPath = Path.Combine(currentDirectoryPath, "envsettings.json");
var envSettings = JObject.Parse(File.ReadAllText(envSettingsPath));
var enviromentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();


var webHostBuilder = new WebHostBuilder()
.UseKestrel()
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseContentRoot(currentDirectoryPath)
.UseIISIntegration()
.UseStartup<Startup>();


// If none is set it use Operative System hosting enviroment
if (!string.IsNullOrWhiteSpace(enviromentValue))
{
webHostBuilder.UseEnvironment(enviromentValue);
}


var host = webHostBuilder.Build();


host.Run();
}
}

If you prefer to use VS features (e.g. VS 2017), it is possible to add Environment variables in the Debug tab of project properties. For example, on the latest ASP.NET Core versions (after RC2) you should set ASPNETCORE_ENVIRONMENT variable.

enter image description here

As result, the launchSettings.json file will be created (or updated) in the Properties folder of the corresponding project, so it will be easy to persist this file into your source control solution and share between developers (as opposite to other solutions with SET / SETX commands)

Note: by default, latest ASP.NET Core set the environment to Production. So, you just need to set ASPNETCORE_ENVIRONMENT to Development in VS for Debugging purposes (see screenshot above). And sure, when you want to run your code locally with Staging environment, you should set ASPNETCORE_ENVIRONMENT to Staging. And finally, when you want to run it on Production environment, just remove this variable or set value to Production.

To summarize: just make sure Development, Staging or Production values are used (not 'Dev' or anything else) in Debug dialog to set environment and make different extensions working.

See also relevant source code from ASP.NET Core:

namespace Microsoft.AspNetCore.Hosting
{
/// <summary>Commonly used environment names.</summary>
public static class EnvironmentName
{
public static readonly string Development = "Development";
public static readonly string Staging = "Staging";
public static readonly string Production = "Production";
}
}


namespace Microsoft.AspNetCore.Hosting
{
/// <summary>
/// Extension methods for <see cref="T:Microsoft.AspNetCore.Hosting.IHostingEnvironment" />.
/// </summary>
public static class HostingEnvironmentExtensions
{
/// <summary>
/// Checks if the current hosting environment name is "Development".
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="T:Microsoft.AspNetCore.Hosting.IHostingEnvironment" />.</param>
/// <returns>True if the environment name is "Development", otherwise false.</returns>
public static bool IsDevelopment(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
throw new ArgumentNullException("hostingEnvironment");
return hostingEnvironment.IsEnvironment(EnvironmentName.Development);
}


/// <summary>
/// Checks if the current hosting environment name is "Staging".
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="T:Microsoft.AspNetCore.Hosting.IHostingEnvironment" />.</param>
/// <returns>True if the environment name is "Staging", otherwise false.</returns>
public static bool IsStaging(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
throw new ArgumentNullException("hostingEnvironment");
return hostingEnvironment.IsEnvironment(EnvironmentName.Staging);
}


/// <summary>
/// Checks if the current hosting environment name is "Production".
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="T:Microsoft.AspNetCore.Hosting.IHostingEnvironment" />.</param>
/// <returns>True if the environment name is "Production", otherwise false.</returns>
public static bool IsProduction(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
throw new ArgumentNullException("hostingEnvironment");
return hostingEnvironment.IsEnvironment(EnvironmentName.Production);
}


/// <summary>
/// Compares the current hosting environment name against the specified value.
/// </summary>
/// <param name="hostingEnvironment">An instance of <see cref="T:Microsoft.AspNetCore.Hosting.IHostingEnvironment" />.</param>
/// <param name="environmentName">Environment name to validate against.</param>
/// <returns>True if the specified name is the same as the current environment, otherwise false.</returns>
public static bool IsEnvironment(this IHostingEnvironment hostingEnvironment, string environmentName)
{
if (hostingEnvironment == null)
throw new ArgumentNullException("hostingEnvironment");
return string.Equals(hostingEnvironment.EnvironmentName, environmentName, StringComparison.OrdinalIgnoreCase);
}
}
}

Here is one more way to set and switch ASPNETCORE_ENVIRONMENT variable in VS2017 (addtional note to @clark-wu answer):

enter image description here

Note: launchSettings.json has two profiles in my case: "IISExpress" and "Project" where ASPNETCORE_ENVIRONMENT is defined.

{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:10000/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/entities",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" // <-- related to IIS Express profile
}
},
"Project": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/entities",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production" // <-- related to Project profile
},
"applicationUrl": "http://localhost:10000/"
}
}
}

Official documentation: You can set ASPNETCORE_ENVIRONMENT to any value, but three values are supported by the framework: Development, Staging, and Production. If ASPNETCORE_ENVIRONMENT isn't set, it defaults to Production.