编程语言
首页 > 编程语言> > 翻译 - ASP.NET Core 基本知识 - 环境(Environments)

翻译 - ASP.NET Core 基本知识 - 环境(Environments)

作者:互联网

翻译自 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-6.0

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

环境

ASP.NET Core 从下列环境变量读取配置决定运行时的环境:

IHostEnvironment.EnvironmentName 可以被设置为任意值,但是下面的值是由框架本身提供的:

下面的代码:

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

Environment Tag Helper 使用 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>
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== 示例代码(sample code)中的 About page 页面包含了上面的标记并且显示了 IWebHostEnvironment.EnvironmentName 的值。

在 Windows 和 macOS上,环境变量和值是不区分大小写的,在 Linux 上是区分大小写的。

创建环境变量示例

本文档中使用的示例代码(sample code)是基于名称为 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 的模板在开发环境中启用了 Developer Exception Page

本机开发环境可以在工程中的 Properties\launchSettings.json 中设置。在 launchSettings.json 中设置的环境值会覆盖系统中的环境变量值。

launchSettings.json 文件:

下面的 JSON 展示了一个使用 Visual Studio 或者 dotnet new 创建的名称为 EnvironmentsSample ASP.NET Core web 工程的 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"
      }
    },
    "EnvironmentsSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

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

commandName 的值指定了要加载的 web 服务器。commandName 的值可以是以下值的其中之一:

Visual Studio 项目属性的 Debug 标签提供了编辑 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"
      }
    }
  }
}

可以通过以下途径选择配置:

dotnet run --launch-profile "SampleApp"

使用  Visual Studio Code 时,环境变量可以在 .vscode/launch.json 文件中设置。下面的示例设置了一些 Host configuration values environment variables

{
    "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 使用。

生产环境

生产环境应该配置为最大安全性,性能好(performance),应用程序的健壮性。一些公共的不同于开发环境的设置包括:

设置环境

使用环境变量或者平台设置用于测试目的设置一个指定的环境通常是有用的。如果环境没有设置,默认是 Production,会禁用大部分的调试特性。设置环境的方法依赖于操作系统。

当主机被创建后,应用程序读取的最后的环境设置决定了应用程序的环境。应用程序的环境在应用程序运行期间不能改变。

示例代码(sample code)中的  About page 展示了 IWebHostEnvironment.EnvironmentName 的值。

Azure 应用程序服务

通过以下步骤在  Azure App Service 中设置环境:

  1. 从 App Services 中选择应用程序
  2. 在 Settings 分组中,选则 Configuration
  3. 在 Application settings 标签中,选择 New application setting
  4. 在 Add/Edit application setting 窗口中,为 Name 提供 ASPNETCORE_ENVIRONMENT  值。对于 Value,提供环境(例如,Staging
  5. 选择 Deployment slot setting 选择框,如果你希望对于当前 slot 的环境设置在 slot 切换的时候仍然保留。更多信息,查看 Azure 文档中的 Set up staging environments in Azure App Service
  6. 选择 Ok 关闭 Add/Edit application setting window
  7. 选择 Configuration 顶部的 Save

Azure 应用程序服务会在一个应用程序设置在 Azure portal 中被添加,改变或者删除后重新启动应用程序。

Windows

launchSettings.json 中的环境值会覆盖系统环境中的值。

当应用程序使用 dotnet run 启动时,在当前会话中,为了设置 ASPNETCORE_ENVIRONMENT  的值,可以使用下面的命令:

Command prompt

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

PowerShell

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

上面命令中对于 ASPNETCORE_ENVIRONMENT  的设置仅仅对于从命令窗口启动的进程起作用。

在 Windows 中设置全局的值,可以使用以下方法之一:

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 Module 中的设置环境变量部分。

项目文件或者发布配置文件

对于在 Windows 上使用 IIS 部署:在发布配置文件(publish profile (.pubxml))或者项目文件中包括有 <EnvironmentName> 属性。这种方法会在项目发布的时候在 web.config 文件中设置环境:

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

Per IIS Application Pool

对于设置一个在隔离的应用程序池运行(IIS 10.0 或者更新版本支持)的应用程序的 ASPNETCORE_ENVIRONMENT 环境变量,请查看 Environment Variables <environmentVariables> 主题的 AppCmd.exe command 部分。当为一个应用程序池设置 ASPNETCORE_ENVIRONMENT  环境变量时,它会覆盖系统级别的设置。

当在 IIS 中托管一个应用程序时,添加或者更改 ASPNETCORE_ENVIRONMENT 环境变量,可以使用以下的任意一种方法获取新的值:

macOS

为 macOS 设置当前环境可以在运行应用程序时执行以下命令:

ASPNETCORE_ENVIRONMENT=Staging dotnet run

或者,在运行应用程序之前使用 export 命令:

export ASPNETCORE_ENVIRONMENT=Staging

Machine-level 的环境变量在 .bashrc 或者 .bash_profile 文件中设置。使用任意的文本编辑器都可以编辑。添加下列语句:

export ASPNETCORE_ENVIRONMENT=Staging

Linux

对于 Linux 发行版,在当前会话使用 export 命令设置环境,使用 bash_profile 文件设置 machine-level 的环境设置。

在代码中设置环境

在创建主机的时候调用 UseEnvironment。查看 .NET Generic Host in ASP.NET Core

通过环境配置

通过环境加载配置,请查看 Configuration in ASP.NET Core

基于环境的 Startup 类和方法

注入 IWebHostEnvironment 到 Startup 类

注入 IWebHostEnvironment 到 Startup 的构造方法。这种方法在应用程序在区分只有几个环境,并且代码量很少的情况下,用来配置 Startup 是很有用的。

在下面的例子中:

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 class )引导应用程序。应用程序可以为不同的环境定义多个 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 方法约定

Configure 和 ConfigureServices 方法支持特定环境版本的 Configure<EnvironmentName> 和 Configure<Environment>Services。如果匹配的 Configure<Environment>Services 或者 Configure<Environment> 方法没有被发现,ConfigureServices 或者 Configure 方法会被使用。这种方法在应用程序在配置启动时需要使用大量代码来区分每一个环境时是有用的:

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

 

标签:Core,ASP,app,Startup,Environments,public,ENVIRONMENT,应用程序,ASPNETCORE
来源: https://blog.csdn.net/hzgisme/article/details/115543980