在 ASP.NET Core 中使用多个环境Use multiple environments in ASP.NET Core

作者:Rick AndersonBy Rick Anderson

ASP.NET Core 基于使用环境变量的运行时环境配置应用行为。ASP.NET Core configures app behavior based on the runtime environment using an environment variable.

查看或下载示例代码如何下载View or download sample code (how to download)

环境Environments

ASP.NET Core 在应用启动时读取环境变量 ASPNETCORE_ENVIRONMENT,并将该值存储在 IWebHostEnvironment.EnvironmentName 中。ASP.NET Core reads the environment variable ASPNETCORE_ENVIRONMENT at app startup and stores the value in IWebHostEnvironment.EnvironmentName. ASPNETCORE_ENVIRONMENT 可设置为任意值,但框架提供三个值:ASPNETCORE_ENVIRONMENT can be set to any value, but three values are provided by the framework:

ASP.NET Core 在应用启动时读取环境变量 ASPNETCORE_ENVIRONMENT,并将该值存储在 IHostingEnvironment.EnvironmentName 中。ASP.NET Core reads the environment variable ASPNETCORE_ENVIRONMENT at app startup and stores the value in IHostingEnvironment.EnvironmentName. ASPNETCORE_ENVIRONMENT 可设置为任意值,但框架提供三个值:ASPNETCORE_ENVIRONMENT can be set to any value, but three values are provided by the framework:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseMvc();
}

前面的代码:The preceding code:

环境标记帮助程序使用 IHostingEnvironment.EnvironmentName 的值来包含或排除元素中的标记:The Environment Tag Helper uses the value of IHostingEnvironment.EnvironmentName to include or exclude markup in the element:

<environment include="Development">
    <div>&lt;environment include="Development"&gt;</div>
</environment>
<environment exclude="Development">
    <div>&lt;environment exclude="Development"&gt;</div>
</environment>
<environment include="Staging,Development,Staging_2">
    <div>
        &lt;environment include="Staging,Development,Staging_2"&gt;
    </div>
</environment>

在 Windows 和 macOS 上,环境变量和值不区分大小写。On Windows and macOS, environment variables and values aren't case sensitive. 默认情况下,Linux 环境变量和值要区分大小写 。Linux environment variables and values are case sensitive by default.

开发Development

开发环境可以启用不应该在生产中公开的功能。The development environment can enable features that shouldn't be exposed in production. 例如,ASP.NET Core 模板在开发环境中启用了开发人员异常页For example, the ASP.NET Core templates enable the Developer Exception Page in the development environment.

本地计算机开发环境可以在项目的 Properties\launchSettings.json 文件中设置 。The environment for local machine development can be set in the Properties\launchSettings.json file of the project. 在 launchSettings.json 中设置的环境值替代在系统环境中设置的值 。Environment values set in launchSettings.json override values set in the system environment.

以下 JSON 显示 launchSettings.json 文件中的三个配置文件 :The following JSON shows three profiles from a launchSettings.json file:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:54339/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_My_Environment": "1",
        "ASPNETCORE_DETAILEDERRORS": "1",
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    },
    "EnvironmentsSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      },
      "applicationUrl": "http://localhost:54340/"
    },
    "Kestrel Staging": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_My_Environment": "1",
        "ASPNETCORE_DETAILEDERRORS": "1",
        "ASPNETCORE_ENVIRONMENT": "Staging"
      },
      "applicationUrl": "http://localhost:51997/"
    }
  }
}

备注

launchSettings.json 中的 applicationUrl 属性可指定服务器 URL 的列表 。The applicationUrl property in launchSettings.json can specify a list of server URLs. 在列表中的 URL 之间使用分号:Use a semicolon between the URLs in the list:

"EnvironmentsSample": {
   "commandName": "Project",
   "launchBrowser": true,
   "applicationUrl": "https://localhost:5001;http://localhost:5000",
   "environmentVariables": {
     "ASPNETCORE_ENVIRONMENT": "Development"
   }
}

使用 dotnet run 启动应用时,使用具有 "commandName": "Project" 的第一个配置文件。When the app is launched with dotnet run, the first profile with "commandName": "Project" is used. commandName 的值指定要启动的 Web 服务器。The value of commandName specifies the web server to launch. commandName 可为以下任一项:commandName can be any one of the following:

  • IISExpress
  • IIS
  • Project(启动 Kestrel 的项目)Project (which launches Kestrel)

使用 dotnet run 启动应用时:When an app is launched with dotnet run:

  • 如果可用,读取 launchSettings.json 。launchSettings.json is read if available. launchSettings.json 中的 environmentVariables 设置会替代环境变量 。environmentVariables settings in launchSettings.json override environment variables.
  • 此时显示承载环境。The hosting environment is displayed.

以下输出显示了使用 dotnet run 启动的应用:The following output shows an app started with dotnet run:

PS C:\Websites\EnvironmentsSample> dotnet run
Using launch settings from C:\Websites\EnvironmentsSample\Properties\launchSettings.json...
Hosting environment: Staging
Content root path: C:\Websites\EnvironmentsSample
Now listening on: http://localhost:54340
Application started. Press Ctrl+C to shut down.

Visual Studio 项目属性“调试”选项卡提供 GUI 来编辑 launchSettings.json 文件 :The Visual Studio project properties Debug tab provides a GUI to edit the launchSettings.json file:

项目属性设置环境变量

在 Web 服务器重新启动之前,对项目配置文件所做的更改可能不会生效。Changes made to project profiles may not take effect until the web server is restarted. 必须重新启动 Kestrel 才能检测到对其环境所做的更改。Kestrel must be restarted before it can detect changes made to its environment.

警告

launchSettings.json 不应存储机密 。launchSettings.json shouldn't store secrets. 机密管理器工具可用于存储本地开发的机密。The Secret Manager tool can be used to store secrets for local development.

使用 Visual Studio Code 时,可以在 .vscode/launch.json 文件中设置环境变量 。When using Visual Studio Code, environment variables can be set in the .vscode/launch.json file. 以下示例将环境设置为 DevelopmentThe following example sets the environment to Development:

{
   "version": "0.2.0",
   "configurations": [
        {
            "name": ".NET Core Launch (web)",

            ... additional VS Code configuration settings ...

            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            }
        }
    ]
}

使用与 Properties/launchSettings.json 相同的方法通过 dotnet run 启动应用时,不读取项目中的 .vscode/launch.json 文件 。A .vscode/launch.json file in the project isn't read when starting the app with dotnet run in the same way as Properties/launchSettings.json. 在没有 launchSettings.json 文件的 Development 环境中启动应用时,需要使用环境变量设置环境或者将命令行参数设为 dotnet run 命令 。When launching an app in development that doesn't have a launchSettings.json file, either set the environment with an environment variable or a command-line argument to the dotnet run command.

生产Production

Production 环境应配置为最大限度地提高安全性、性能和应用可靠性。The production environment should be configured to maximize security, performance, and app robustness. 不同于开发的一些通用设置包括:Some common settings that differ from development include:

  • 缓存。Caching.
  • 客户端资源被捆绑和缩小,并可能从 CDN 提供。Client-side resources are bundled, minified, and potentially served from a CDN.
  • 已禁用诊断错误页。Diagnostic error pages disabled.
  • 已启用友好错误页。Friendly error pages enabled.
  • 已启用生产记录和监视。Production logging and monitoring enabled. 例如,Application InsightsFor example, Application Insights.

设置环境Set the environment

通常,可以使用环境变量或平台设置来设置用于测试的特定环境。It's often useful to set a specific environment for testing with an environment variable or platform setting. 如果未设置环境,默认值为 Production,这会禁用大多数调试功能。If the environment isn't set, it defaults to Production, which disables most debugging features. 设置环境的方法取决于操作系统。The method for setting the environment depends on the operating system.

构建主机时,应用读取的最后一个环境设置将决定应用的环境。When the host is built, the last environment setting read by the app determines the app's environment. 应用运行时无法更改应用的环境。The app's environment can't be changed while the app is running.

环境变量或平台设置Environment variable or platform setting

Azure 应用服务Azure App Service

若要在 Azure 应用服务中设置环境,请执行以下步骤:To set the environment in Azure App Service, perform the following steps:

  1. 从“应用服务”边栏选项卡中选择应用 。Select the app from the App Services blade.
  2. 在“设置”组中,选择“应用程序设置”边栏选项卡 。In the SETTINGS group, select the Application settings blade.
  3. 在“应用程序设置”区域中,选择“添加新设置” 。In the Application settings area, select Add new setting.
  4. 在“输入名称”中提供 ASPNETCORE_ENVIRONMENTFor Enter a name, provide ASPNETCORE_ENVIRONMENT. 在“输入值”中提供环境(例如 Staging) 。For Enter a value, provide the environment (for example, Staging).
  5. 交换部署槽位时,如果希望环境设置保持当前槽位,请选中“槽位设置”复选框 。Select the Slot Setting check box if you wish the environment setting to remain with the current slot when deployment slots are swapped. 有关详细信息,请参阅 Azure 文档:交换哪些设置?For more information, see Azure Documentation: Which settings are swapped?.
  6. 选择边栏选项卡顶部的“保存” 。Select Save at the top of the blade.

在 Azure 门户中添加、更改或删除应用设置(环境变量)后,Azure 应用服务自动重启应用。Azure App Service automatically restarts the app after an app setting (environment variable) is added, changed, or deleted in the Azure portal.

WindowsWindows

若要在使用 dotnet run 启动该应用时为当前会话设置 ASPNETCORE_ENVIRONMENT,则使用以下命令:To set the ASPNETCORE_ENVIRONMENT for the current session when the app is started using dotnet run, the following commands are used:

命令提示符Command prompt

set ASPNETCORE_ENVIRONMENT=Development

PowerShellPowerShell

$Env:ASPNETCORE_ENVIRONMENT = "Development"

这些命令仅对当前窗口有效。These commands only take effect for the current window. 窗口关闭时,ASPNETCORE_ENVIRONMENT 设置将恢复为默认设置或计算机值。When the window is closed, the ASPNETCORE_ENVIRONMENT setting reverts to the default setting or machine value.

若要在 Windows 中全局设置值,请采用下列两种方法之一:To set the value globally in Windows, use either of the following approaches:

  • 依次打开“控制面板” > “系统” > “高级系统设置” ,再添加或编辑“ASPNETCORE_ENVIRONMENT”值:Open the Control Panel > System > Advanced system settings and add or edit the ASPNETCORE_ENVIRONMENT value:

    系统高级属性

    ASPNET Core 环境变量

  • 打开管理命令提示符并运行 setx 命令,或打开管理 PowerShell 命令提示符并运行 [Environment]::SetEnvironmentVariableOpen an administrative command prompt and use the setx command or open an administrative PowerShell command prompt and use [Environment]::SetEnvironmentVariable:

    命令提示符Command prompt

    setx ASPNETCORE_ENVIRONMENT Development /M
    

    /M 开关指明,在系统一级设置环境变量。The /M switch indicates to set the environment variable at the system level. 如果未使用 /M 开关,就会为用户帐户设置环境变量。If the /M switch isn't used, the environment variable is set for the user account.

    PowerShellPowerShell

    [Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "Machine")
    

    Machine 选项值指明,在系统一级设置环境变量。The Machine option value indicates to set the environment variable at the system level. 如果将选项值更改为 User,就会为用户帐户设置环境变量。If the option value is changed to User, the environment variable is set for the user account.

如果全局设置 ASPNETCORE_ENVIRONMENT 环境变量,它就会对在值设置后打开的任何命令窗口中对 dotnet run 起作用。When the ASPNETCORE_ENVIRONMENT environment variable is set globally, it takes effect for dotnet run in any command window opened after the value is set.

web.configweb.config

若要使用 web.config 设置 ASPNETCORE_ENVIRONMENT 环境变量,请参阅 ASP.NET Core 模块的“设置环境变量” 部分。To set the ASPNETCORE_ENVIRONMENT environment variable with web.config, see the Setting environment variables section of ASP.NET Core 模块.

项目文件或发布配置文件Project file or publish profile

对于 Windows IIS 部署:<EnvironmentName> 属性包含在发布配置文件 (.pubxml) 或项目文件中。For Windows IIS deployments: Include the <EnvironmentName> property in the publish profile (.pubxml) or project file. 此方法在发布项目时设置 web.config 中的环境:This approach sets the environment in web.config when the project is published:

<PropertyGroup>
  <EnvironmentName>Development</EnvironmentName>
</PropertyGroup>

每个 IIS 应用程序池Per IIS Application Pool

若要为在独立应用池中运行的应用设置 ASPNETCORE_ENVIRONMENT 环境变量(IIS 10.0 或更高版本支持此操作),请参阅环境变量 <environmentVariables> 主题中的“AppCmd.exe 命令” 部分。To set the ASPNETCORE_ENVIRONMENT environment variable for an app running in an isolated Application Pool (supported on IIS 10.0 or later), see the AppCmd.exe command section of the Environment Variables <environmentVariables> topic. 为应用池设置 ASPNETCORE_ENVIRONMENT 环境变量后,它的值会替代系统级设置。When the ASPNETCORE_ENVIRONMENT environment variable is set for an app pool, its value overrides a setting at the system level.

重要

在 IIS 中托管应用并添加或更改 ASPNETCORE_ENVIRONMENT 环境变量时,请采用下列方法之一,让新值可供应用拾取:When hosting an app in IIS and adding or changing the ASPNETCORE_ENVIRONMENT environment variable, use any one of the following approaches to have the new value picked up by apps:

  • 在命令提示符处依次执行 net stop was /ynet start w3svcExecute net stop was /y followed by net start w3svc from a command prompt.
  • 重新启动服务器。Restart the server.

macOSmacOS

设置 macOS 的当前环境可在运行应用时完成:Setting the current environment for macOS can be performed in-line when running the app:

ASPNETCORE_ENVIRONMENT=Development dotnet run

或者,在运行应用前使用 export 设置环境:Alternatively, set the environment with export prior to running the app:

export ASPNETCORE_ENVIRONMENT=Development

在 .bashrc 或 .bash_profile 文件中设置计算机级环境变量 。Machine-level environment variables are set in the .bashrc or .bash_profile file. 使用任意文本编辑器编辑文件。Edit the file using any text editor. 添加以下语句:Add the following statement:

export ASPNETCORE_ENVIRONMENT=Development

LinuxLinux

对于 Linux 发行版,请在命令提示符中使用 export 命令进行基于会话的变量设置,并使用 bash_profile 文件进行计算机级环境设置 。For Linux distros, use the export command at a command prompt for session-based variable settings and bash_profile file for machine-level environment settings.

使用代码设置环境Set the environment in code

生成主机时,调用 UseEnvironmentCall UseEnvironment when building the host. 请参阅 .NET 通用主机See .NET 通用主机.

生成主机时,调用 UseEnvironmentCall UseEnvironment when building the host. 请参阅 ASP.NET Core Web 主机See ASP.NET Core Web 主机.

按环境配置Configuration by environment

若要按环境加载配置,我们建议:To load configuration by environment, we recommend:

基于环境的 Startup 类和方法Environment-based Startup class and methods

将 IWebHostEnvironment 注入 Startup.ConfigureInject IWebHostEnvironment into Startup.Configure

IWebHostEnvironment 注入 Startup.ConfigureInject IWebHostEnvironment into Startup.Configure. 当应用仅需为几个代码差异最小的环境调整 Startup.Configure 时,这种方法非常有用。This approach is useful when the app only requires adjusting Startup.Configure for a few environments with minimal code differences per environment.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Development environment code
    }
    else
    {
        // Code for all other environments
    }
}

将 IWebHostEnvironment 注入 Startup 类Inject IWebHostEnvironment into the Startup class

IWebHostEnvironment 注入 Startup 构造函数。Inject IWebHostEnvironment into the Startup constructor. 当应用仅需为几个代码差异最小的环境配置 Startup 时,这种方法非常有用。This approach is useful when the app requires configuring Startup for only a few environments with minimal code differences per environment.

如下示例中:In the following example:

  • 环境保存在 _env 字段中。The environment is held in the _env field.
  • _envConfigureServicesConfigure 中用于根据应用的环境应用启动配置。_env is used in ConfigureServices and Configure to apply startup configuration based on the app's environment.
public class Startup
{
    private readonly IWebHostEnvironment _env;

    public Startup(IWebHostEnvironment env)
    {
        _env = env;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        if (_env.IsDevelopment())
        {
            // Development environment code
        }
        else if (_env.IsStaging())
        {
            // Staging environment code
        }
        else
        {
            // Code for all other environments
        }
    }

    public void Configure(IApplicationBuilder app)
    {
        if (_env.IsDevelopment())
        {
            // Development environment code
        }
        else
        {
            // Code for all other environments
        }
    }
}

将 IHostingEnvironment 注入 Startup.ConfigureInject IHostingEnvironment into Startup.Configure

IHostingEnvironment 注入 Startup.ConfigureInject IHostingEnvironment into Startup.Configure. 当应用仅需为几个代码差异最小的环境配置 Startup.Configure 时,这种方法非常有用。This approach is useful when the app only requires configuring Startup.Configure for only a few environments with minimal code differences per environment.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Development environment code
    }
    else
    {
        // Code for all other environments
    }
}

将 IHostingEnvironment 注入 Startup 类Inject IHostingEnvironment into the Startup class

IHostingEnvironment 注入 Startup 构造函数,并将服务分配给一个字段,以便在整个 Startup 类中使用。Inject IHostingEnvironment into the Startup constructor and assign the service to a field for use throughout the Startup class. 当应用需为几个代码差异最小的环境配置启动时,这种方法非常有用。This approach is useful when the app requires configuring startup for only a few environments with minimal code differences per environment.

如下示例中:In the following example:

  • 环境保存在 _env 字段中。The environment is held in the _env field.
  • _envConfigureServicesConfigure 中用于根据应用的环境应用启动配置。_env is used in ConfigureServices and Configure to apply startup configuration based on the app's environment.
public class Startup
{
    private readonly IHostingEnvironment _env;

    public Startup(IHostingEnvironment env)
    {
        _env = env;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        if (_env.IsDevelopment())
        {
            // Development environment code
        }
        else if (_env.IsStaging())
        {
            // Staging environment code
        }
        else
        {
            // Code for all other environments
        }
    }

    public void Configure(IApplicationBuilder app)
    {
        if (_env.IsDevelopment())
        {
            // Development environment code
        }
        else
        {
            // Code for all other environments
        }
    }
}

Startup 类约定Startup class conventions

当 ASP.NET Core 应用启动时,Startup 类启动应用。When an ASP.NET Core app starts, the Startup class bootstraps the app. 应用可以为不同的环境定义单独的 Startup 类(例如 StartupDevelopment)。The app can define separate Startup classes for different environments (for example, StartupDevelopment). 在运行时选择适当的 Startup 类。The appropriate Startup class is selected at runtime. 优先考虑名称后缀与当前环境相匹配的类。The class whose name suffix matches the current environment is prioritized. 如果找不到匹配的 Startup{EnvironmentName},就会使用 Startup 类。If a matching Startup{EnvironmentName} class isn't found, the Startup class is used. 当应用需要为各环境之间存在许多代码差异的多个环境配置启动时,这种方法非常有用。This approach is useful when the app requires configuring startup for several environments with many code differences per environment.

若要实现基于环境的 Startup 类,请为使用中的每个环境创建 Startup{EnvironmentName} 类,并创建回退 Startup 类:To implement environment-based Startup classes, create a Startup{EnvironmentName} class for each environment in use and a fallback Startup class:

// Startup class to use in the Development environment
public class StartupDevelopment
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

// Startup class to use in the Production environment
public class StartupProduction
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

// Fallback Startup class
// Selected if the environment doesn't match a Startup{EnvironmentName} class
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

使用接受程序集名称的 UseStartup(IWebHostBuilder, String) 重载:Use the UseStartup(IWebHostBuilder, String) overload that accepts an assembly name:

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    var assemblyName = typeof(Startup).GetTypeInfo().Assembly.FullName;

    return WebHost.CreateDefaultBuilder(args)
        .UseStartup(assemblyName);
}

Startup 方法约定Startup method conventions

ConfigureConfigureServices 支持窗体 Configure<EnvironmentName>Configure<EnvironmentName>Services 的环境特定版本。Configure and ConfigureServices support environment-specific versions of the form Configure<EnvironmentName> and Configure<EnvironmentName>Services. 当应用需要为各环境之间存在许多代码差异的多个环境配置启动时,这种方法非常有用。This approach is useful when the app requires configuring startup for several environments with many code differences per environment.

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        StartupConfigureServices(services);
    }

    public void ConfigureStagingServices(IServiceCollection services)
    {
        StartupConfigureServices(services);
    }

    private void StartupConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
        {
            app.UseExceptionHandler("/Error");
        }

        app.UseStaticFiles();
        app.UseMvc();
    }

    public void ConfigureStaging(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (!env.IsStaging())
        {
            throw new Exception("Not staging.");
        }

        app.UseExceptionHandler("/Error");
        app.UseStaticFiles();
        app.UseMvc();
    }
}

其他资源Additional resources