在 ASP.NET Core 中使用多个环境

作者:Rick AndersonKirk Larkin

ASP.NET Core 基于使用环境变量的运行时环境配置应用行为。

查看或下载示例代码如何下载

环境

为了确定运行时环境,ASP.NET Core 从以下环境变量中读取信息:

  1. DOTNET_ENVIRONMENT
  2. ASPNETCORE_ENVIRONMENT(当调用 ConfigureWebHostDefaults 时)。 默认 ASP.NET Core Web 应用模板调用 ConfigureWebHostDefaultsASPNETCORE_ENVIRONMENT 值替代 DOTNET_ENVIRONMENT

IHostEnvironment.EnvironmentName 可以设置为任意值,但是框架提供了下列值:

下面的代码:

  • ASPNETCORE_ENVIRONMENT 设置为 Development 时,调用 UseDeveloperExceptionPage
  • ASPNETCORE_ENVIRONMENT 的值设置为 StagingProductionStaging_2 时,调用 UseExceptionHandler
  • IWebHostEnvironment 注入到 Startup.Configure 中。 当应用仅需为几个代码差异最小的环境调整 Startup.Configure 时,这种方法非常有用。
  • 类似于由 ASP.NET Core 模板生成的代码。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

环境标记帮助程序使用 IHostEnvironment.EnvironmentName 的值在元素中包含或排除标记:

<environment include="Development">
    <div>The effective tag is: &lt;environment include="Development"&gt;</div>
</environment>
<environment exclude="Development">
    <div>The effective tag is: &lt;environment exclude="Development"&gt;</div>
</environment>
<environment include="Staging,Development,Staging_2">
    <div>
        The effective tag is:
        &lt;environment include="Staging,Development,Staging_2"&gt;
    </div>
</environment>

示例代码中的“关于”页包括前面的标记,并显示 IWebHostEnvironment.EnvironmentName 的值。

在 Windows 和 macOS 上,环境变量和值不区分大小写。 默认情况下,Linux 环境变量和值区分大小写。

创建 EnvironmentsSample

本文档中使用的示例代码基于名为“EnvironmentsSample”的 Razor Pages 项目。

以下代码创建并运行名为“EnvironmentsSample”的 Web 应用:

dotnet new webapp -o EnvironmentsSample
cd EnvironmentsSample
dotnet run --verbosity normal

当应用运行时,它会显示下面的部分输出内容:

Using launch settings from c:\tmp\EnvironmentsSample\Properties\launchSettings.json
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: c:\tmp\EnvironmentsSample

开发和 launchSettings.json

开发环境可以启用不应该在生产中公开的功能。 例如,ASP.NET Core 模板在开发环境中启用了开发人员异常页

本地计算机开发环境可以在项目的 Properties\launchSettings.json 文件中设置。 在 launchSettings.json 中设置的环境值替代在系统环境中设置的值。

launchSettings.json 文件:

  • 仅在本地开发计算机上使用。
  • 未部署。
  • 包含配置文件设置。

下面的 JSON 显示名为“EnvironmentsSample”的 ASP.NET Core Web 项目的 launchSettings.json 文件,此项目是通过 Visual Studio 或 dotnet new 创建的:

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:64645",
      "sslPort": 44366
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "EnvironmentsSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

前面的标记包含两个配置文件:

  • IIS Express:在 Visual Studio 中启动应用时使用的默认配置文件。 由于 "commandName" 键的值为 "IISExpress",因此 IISExpress 是 Web 服务器。 可以将启动配置文件设置为此项目或所包含的其他任何配置文件。 例如,在下图中,选择项目名称会启动 Kestrel Web 服务器

    使用菜单启动 IIS Express

  • EnvironmentsSample:配置文件名称是项目名称。 当使用 dotnet run 启动应用时,默认使用此配置文件。 由于 "commandName" 键的值为 "Project",因此启动的是 Kestrel Web 服务器

commandName 的值可指定要启动的 Web 服务器。 commandName 可为以下任一项:

  • IISExpress:启动 IIS Express。
  • IIS:不启动任何 Web 服务器。 IIS 预计可用。
  • Project:启动 Kestrel。

Visual Studio 项目属性“调试”选项卡提供了 GUI 来编辑 launchSettings.json 文件。 在 Web 服务器重新启动之前,对项目配置文件所做的更改可能不会生效。 必须重新启动 Kestrel 才能检测到对其环境所做的更改。

项目属性设置环境变量

以下 launchSettings.json 文件包含多个配置文件:

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:64645",
      "sslPort": 44366
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IISX-Production": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      }
    },
    "IISX-Staging": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging",
        "ASPNETCORE_DETAILEDERRORS": "1",
        "ASPNETCORE_SHUTDOWNTIMEOUTSECONDS": "3"
      }
    },
    "EnvironmentsSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "KestrelStaging": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    }
  }
}

可通过以下方式来选择配置文件:

  • 在 Visual Studio UI 中。

  • 在命令行界面中使用 dotnet run 命令,并将 --launch-profile 选项设置为配置文件名称。 这种方法只支持 Kestrel 配置文件。

    dotnet run --launch-profile "SampleApp"
    

警告

launchSettings.json 不应存储机密。 机密管理器工具可用于存储本地开发的机密。

使用 Visual Studio Code 时,可以在 .vscode/launch.json 文件中设置环境变量。 下面的示例设置了多个主机配置值环境变量

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (web)",
            "type": "coreclr",
            // Configuration ommitted for brevity.
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development",
                "ASPNETCORE_URLS": "https://localhost:5001",
                "ASPNETCORE_DETAILEDERRORS": "1",
                "ASPNETCORE_SHUTDOWNTIMEOUTSECONDS": "3"
            },
            // Configuration ommitted for brevity.

.vscode/launch.json 文件仅由 Visual Studio Code 使用。

生产

生产环境应配置为最大限度地提高安全性、性能和应用可靠性。 不同于开发的一些通用设置包括:

  • 缓存
  • 客户端资源被捆绑和缩小,并可能从 CDN 提供。
  • 已禁用诊断错误页。
  • 已启用友好错误页。
  • 已启用生产记录和监视。 例如,使用 Application Insights

设置环境

通常,可以使用环境变量或平台设置来设置用于测试的特定环境。 如果未设置环境,默认值为 Production,这会禁用大多数调试功能。 设置环境的方法取决于操作系统。

构建主机时,应用读取的最后一个环境设置将决定应用的环境。 应用运行时无法更改应用的环境。

示例代码中的“关于”页显示 IWebHostEnvironment.EnvironmentName 的值。

Azure 应用服务

若要在 Azure 应用服务中设置环境,请执行以下步骤:

  1. 从“应用服务”边栏选项卡中选择应用。
  2. 在“设置”组中,选择“配置”边栏选项卡 。
  3. 在“应用程序设置”选项卡中,选择“新建应用程序设置”。
  4. 在“添加/编辑应用程序设置”窗口中,在“名称”中提供 ASPNETCORE_ENVIRONMENT。 在“值”中提供环境(例如 Staging)。
  5. 交换部署槽位时,如果希望环境设置保持当前槽位,请选中“部署槽位设置”复选框。 有关详细信息,请参阅 Azure 文档中的在 Azure 应用服务中设置过渡环境
  6. 选择“确定”以关闭“添加/编辑应用程序设置”窗口。
  7. 选择“配置”边栏选项卡顶部的“保存” 。

在 Azure 门户中添加、更改或删除应用设置后,Azure 应用服务自动重启应用。

Windows

launchSettings.json 中的环境值替代在系统环境中设置的值。

若要在使用 dotnet run 启动该应用时为当前会话设置 ASPNETCORE_ENVIRONMENT,则使用以下命令:

命令提示符

set ASPNETCORE_ENVIRONMENT=Staging
dotnet run --no-launch-profile

PowerShell

$Env:ASPNETCORE_ENVIRONMENT = "Staging"
dotnet run --no-launch-profile

前面的命令只为通过此命令窗口启动的进程设置 ASPNETCORE_ENVIRONMENT

若要在 Windows 中全局设置值,请采用下列两种方法之一:

  • 依次打开“控制面板”>“系统”>“高级系统设置”,再添加或编辑“ASPNETCORE_ENVIRONMENT”值:

    系统高级属性

    ASPNET Core 环境变量

  • 打开管理命令提示符并运行 setx 命令,或打开管理 PowerShell 命令提示符并运行 [Environment]::SetEnvironmentVariable

    命令提示符

    setx ASPNETCORE_ENVIRONMENT Staging /M
    

    /M 开关指明,在系统一级设置环境变量。 如果未使用 /M 开关,就会为用户帐户设置环境变量。

    PowerShell

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

    Machine 选项值指明,在系统一级设置环境变量。 如果将选项值更改为 User,就会为用户帐户设置环境变量。

如果全局设置 ASPNETCORE_ENVIRONMENT 环境变量,它就会对在值设置后打开的任何命令窗口中对 dotnet run 起作用。 launchSettings.json 中的环境值替代在系统环境中设置的值。

web.config

若要使用 web.config 设置 ASPNETCORE_ENVIRONMENT 环境变量,请参阅 ASP.NET Core 模块的“设置环境变量”部分。

项目文件或发布配置文件

对于 Windows IIS 部署:<EnvironmentName> 属性包含在发布配置文件 (.pubxml) 或项目文件中。 此方法在发布项目时设置 web.config 中的环境:

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

每个 IIS 应用程序池

若要为在独立应用池中运行的应用设置 ASPNETCORE_ENVIRONMENT 环境变量(IIS 10.0 或更高版本支持此操作),请参阅环境变量 <environmentVariables> 主题中的“AppCmd.exe 命令”部分。 为应用池设置 ASPNETCORE_ENVIRONMENT 环境变量后,它的值会替代系统级设置。

在 IIS 中托管应用并添加或更改 ASPNETCORE_ENVIRONMENT 环境变量时,请采用下列方法之一,让新值可供应用拾取:

  • 在命令提示符处依次执行 net stop was /ynet start w3svc
  • 重新启动服务器。

macOS

设置 macOS 的当前环境可在运行应用时完成:

ASPNETCORE_ENVIRONMENT=Staging dotnet run

或者,在运行应用前使用 export 设置环境:

export ASPNETCORE_ENVIRONMENT=Staging

在 .bashrc 或 .bash_profile 文件中设置计算机级环境变量 。 使用任意文本编辑器编辑文件。 添加以下语句:

export ASPNETCORE_ENVIRONMENT=Staging

Linux

对于 Linux 发行版,在命令提示符处对基于会话的变量设置使用 export 命令,并对计算机级别环境设置使用 bash_profile 文件。

使用代码设置环境

生成主机时,调用 UseEnvironment。 请参阅 ASP.NET Core 中的 .NET 通用主机

按环境配置

若要按环境加载配置,请参阅 ASP.NET Core 中的配置

基于环境的 Startup 类和方法

将 IWebHostEnvironment 注入 Startup 类

IWebHostEnvironment 注入 Startup 构造函数。 当应用仅需为几个代码差异最小的环境配置 Startup 时,这种方法非常有用。

如下示例中:

  • 环境保存在 _env 字段中。
  • _envConfigureServicesConfigure 中用于根据应用的环境应用启动配置。
public class Startup
{
    public Startup(IConfiguration configuration, IWebHostEnvironment env)
    {
        Configuration = configuration;
        _env = env;
    }

    public IConfiguration Configuration { get; }
    private readonly IWebHostEnvironment _env;

    public void ConfigureServices(IServiceCollection services)
    {
        if (_env.IsDevelopment())
        {
            Console.WriteLine(_env.EnvironmentName);
        }
        else if (_env.IsStaging())
        {
            Console.WriteLine(_env.EnvironmentName);
        }
        else
        {
            Console.WriteLine("Not dev or staging");
        }

        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {
        if (_env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Startup 类约定

当 ASP.NET Core 应用启动时,Startup 类启动应用。 应用可以为不同的环境定义多个 Startup 类。 在运行时选择适当的 Startup 类。 优先考虑名称后缀与当前环境相匹配的类。 如果找不到匹配的 Startup{EnvironmentName},就会使用 Startup 类。 当应用需要为各环境之间存在许多代码差异的多个环境配置启动时,这种方法非常有用。 典型的应用不需要这种方法。

若要实现基于环境的 Startup 类,请创建 Startup{EnvironmentName} 类和回退 Startup 类:

public class StartupDevelopment
{
    public StartupDevelopment(IConfiguration configuration)
    {
        Configuration = configuration;
        Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseDeveloperExceptionPage();

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

public class StartupProduction
{
    public StartupProduction(IConfiguration configuration)
    {
        Configuration = configuration;
        Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {

        app.UseExceptionHandler("/Error");
        app.UseHsts();

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

使用接受程序集名称的 UseStartup(IWebHostBuilder, String) 重载:

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

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

        return   Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup(assemblyName);
            });
    }
}

Startup 方法约定

ConfigureConfigureServices 支持窗体 Configure<EnvironmentName>Configure<EnvironmentName>Services 的环境特定版本。 当应用需要为多个环境(每个环境有许多代码差异)配置启动时,这种方法就非常有用:

public class Startup
{
    private void StartupConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void ConfigureDevelopmentServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void ConfigureStagingServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void ConfigureProductionServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void ConfigureServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        MyTrace.TraceMessage();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }

    public void ConfigureStaging(IApplicationBuilder app, IWebHostEnvironment env)
    {
        MyTrace.TraceMessage();

        app.UseExceptionHandler("/Error");
        app.UseHsts();

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

public static class MyTrace
{
    public static void TraceMessage([CallerMemberName] string memberName = "")
    {
        Console.WriteLine($"Method: {memberName}");
    }
}

其他资源

作者:Rick Anderson

ASP.NET Core 基于使用环境变量的运行时环境配置应用行为。

查看或下载示例代码如何下载

环境

ASP.NET Core 在应用启动时读取环境变量 ASPNETCORE_ENVIRONMENT,并将该值存储在 IHostingEnvironment.EnvironmentName 中。 ASPNETCORE_ENVIRONMENT 可设置为任意值,但框架提供三个值:

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();
}

前面的代码:

环境标记帮助程序使用 IHostingEnvironment.EnvironmentName 的值来包含或排除元素中的标记:

<environment include="Development">
    <div>The effective tag is: &lt;environment include="Development"&gt;</div>
</environment>
<environment exclude="Development">
    <div>The effective tag is: &lt;environment exclude="Development"&gt;</div>
</environment>
<environment include="Staging,Development,Staging_2">
    <div>
        The effective tag is:
        &lt;environment include="Staging,Development,Staging_2"&gt;
    </div>
</environment>

在 Windows 和 macOS 上,环境变量和值不区分大小写。 默认情况下,Linux 环境变量和值区分大小写。

开发

开发环境可以启用不应该在生产中公开的功能。 例如,ASP.NET Core 模板在开发环境中启用了开发人员异常页

本地计算机开发环境可以在项目的 Properties\launchSettings.json 文件中设置。 在 launchSettings.json 中设置的环境值替代在系统环境中设置的值。

以下 JSON 显示 launchSettings.json 文件中的三个配置文件:

{
  "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 的列表。 在列表中的 URL 之间使用分号:

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

使用 dotnet run 启动应用时,使用具有 "commandName": "Project" 的第一个配置文件。 commandName 的值指定要启动的 Web 服务器。 commandName 可为以下任一项:

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

使用 dotnet run 启动应用时:

  • 如果可用,读取 launchSettings.json。 launchSettings.json 中的 environmentVariables 设置会替代环境变量。
  • 此时显示承载环境。

以下输出显示了使用 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 文件:

项目属性设置环境变量

在 Web 服务器重新启动之前,对项目配置文件所做的更改可能不会生效。 必须重新启动 Kestrel 才能检测到对其环境所做的更改。

警告

launchSettings.json 不应存储机密。 机密管理器工具可用于存储本地开发的机密。

使用 Visual Studio Code 时,可以在 .vscode/launch.json 文件中设置环境变量。 以下示例将环境设置为 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 文件 。 在没有 launchSettings.json 文件的 Development 环境中启动应用时,需要使用环境变量设置环境或者将命令行参数设为 dotnet run 命令。

生产

Production 环境应配置为最大限度地提高安全性、性能和应用可靠性。 不同于开发的一些通用设置包括:

  • 缓存。
  • 客户端资源被捆绑和缩小,并可能从 CDN 提供。
  • 已禁用诊断错误页。
  • 已启用友好错误页。
  • 已启用生产记录和监视。 例如,Application Insights

设置环境

通常,可以使用环境变量或平台设置来设置用于测试的特定环境。 如果未设置环境,默认值为 Production,这会禁用大多数调试功能。 设置环境的方法取决于操作系统。

构建主机时,应用读取的最后一个环境设置将决定应用的环境。 应用运行时无法更改应用的环境。

环境变量或平台设置

Azure 应用服务

若要在 Azure 应用服务中设置环境,请执行以下步骤:

  1. 从“应用服务”边栏选项卡中选择应用。
  2. 在“设置”组中,选择“配置”边栏选项卡 。
  3. 在“应用程序设置”选项卡中,选择“新建应用程序设置”。
  4. 在“添加/编辑应用程序设置”窗口中,在“名称”中提供 ASPNETCORE_ENVIRONMENT。 在“值”中提供环境(例如 Staging)。
  5. 交换部署槽位时,如果希望环境设置保持当前槽位,请选中“部署槽位设置”复选框。 有关详细信息,请参阅 Azure 文档中的在 Azure 应用服务中设置过渡环境
  6. 选择“确定”以关闭“添加/编辑应用程序设置”窗口。
  7. 选择“配置”边栏选项卡顶部的“保存” 。

在 Azure 门户中添加、更改或删除应用设置(环境变量)后,Azure 应用服务自动重启应用。

Windows

若要在使用 dotnet run 启动该应用时为当前会话设置 ASPNETCORE_ENVIRONMENT,则使用以下命令:

命令提示符

set ASPNETCORE_ENVIRONMENT=Development

PowerShell

$Env:ASPNETCORE_ENVIRONMENT = "Development"

这些命令仅对当前窗口有效。 窗口关闭时,ASPNETCORE_ENVIRONMENT 设置将恢复为默认设置或计算机值。

若要在 Windows 中全局设置值,请采用下列两种方法之一:

  • 依次打开“控制面板”>“系统”>“高级系统设置”,再添加或编辑“ASPNETCORE_ENVIRONMENT”值:

    系统高级属性

    ASPNET Core 环境变量

  • 打开管理命令提示符并运行 setx 命令,或打开管理 PowerShell 命令提示符并运行 [Environment]::SetEnvironmentVariable

    命令提示符

    setx ASPNETCORE_ENVIRONMENT Development /M
    

    /M 开关指明,在系统一级设置环境变量。 如果未使用 /M 开关,就会为用户帐户设置环境变量。

    PowerShell

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

    Machine 选项值指明,在系统一级设置环境变量。 如果将选项值更改为 User,就会为用户帐户设置环境变量。

如果全局设置 ASPNETCORE_ENVIRONMENT 环境变量,它就会对在值设置后打开的任何命令窗口中对 dotnet run 起作用。

web.config

若要使用 web.config 设置 ASPNETCORE_ENVIRONMENT 环境变量,请参阅 ASP.NET Core 模块的“设置环境变量”部分。

项目文件或发布配置文件

对于 Windows IIS 部署:<EnvironmentName> 属性包含在发布配置文件 (.pubxml) 或项目文件中。 此方法在发布项目时设置 web.config 中的环境:

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

每个 IIS 应用程序池

若要为在独立应用池中运行的应用设置 ASPNETCORE_ENVIRONMENT 环境变量(IIS 10.0 或更高版本支持此操作),请参阅环境变量 <environmentVariables> 主题中的“AppCmd.exe 命令”部分。 为应用池设置 ASPNETCORE_ENVIRONMENT 环境变量后,它的值会替代系统级设置。

重要

在 IIS 中托管应用并添加或更改 ASPNETCORE_ENVIRONMENT 环境变量时,请采用下列方法之一,让新值可供应用拾取:

  • 在命令提示符处依次执行 net stop was /ynet start w3svc
  • 重新启动服务器。

macOS

设置 macOS 的当前环境可在运行应用时完成:

ASPNETCORE_ENVIRONMENT=Development dotnet run

或者,在运行应用前使用 export 设置环境:

export ASPNETCORE_ENVIRONMENT=Development

在 .bashrc 或 .bash_profile 文件中设置计算机级环境变量 。 使用任意文本编辑器编辑文件。 添加以下语句:

export ASPNETCORE_ENVIRONMENT=Development

Linux

对于 Linux 发行版,在命令提示符处对基于会话的变量设置使用 export 命令,并对计算机级别环境设置使用 bash_profile 文件。

使用代码设置环境

生成主机时,调用 UseEnvironment。 请参阅 ASP.NET Core Web 主机

按环境配置

若要按环境加载配置,我们建议:

基于环境的 Startup 类和方法

将 IHostingEnvironment 注入 Startup.Configure

IHostingEnvironment 注入 Startup.Configure。 当应用仅需为几个代码差异最小的环境配置 Startup.Configure 时,这种方法非常有用。

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

将 IHostingEnvironment 注入 Startup 类

IHostingEnvironment 注入 Startup 构造函数,并将服务分配给一个字段,以便在整个 Startup 类中使用。 当应用需为几个代码差异最小的环境配置启动时,这种方法非常有用。

如下示例中:

  • 环境保存在 _env 字段中。
  • _envConfigureServicesConfigure 中用于根据应用的环境应用启动配置。
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 类约定

当 ASP.NET Core 应用启动时,Startup 类启动应用。 应用可以为不同的环境定义单独的 Startup 类(例如 StartupDevelopment)。 在运行时选择适当的 Startup 类。 优先考虑名称后缀与当前环境相匹配的类。 如果找不到匹配的 Startup{EnvironmentName},就会使用 Startup 类。 当应用需要为各环境之间存在许多代码差异的多个环境配置启动时,这种方法非常有用。

若要实现基于环境的 Startup 类,请为使用中的每个环境创建 Startup{EnvironmentName} 类,并创建回退 Startup 类:

// 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) 重载:

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 方法约定

ConfigureConfigureServices 支持窗体 Configure<EnvironmentName>Configure<EnvironmentName>Services 的环境特定版本。 当应用需要为各环境之间存在许多代码差异的多个环境配置启动时,这种方法非常有用。

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();
    }
}

其他资源