在ASP.NET Core中自带了一些内置对象,可以读取到当前程序处于什么样的环境当中,比如在ASP.NET Core的Startup类的Configure方法中,我们就会看到这么一段代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles();
app.UseCookiePolicy(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}

其中env.IsDevelopment()就可以读出当前程序是否是处于开发环境当中,如果你在Visual Studio中运行ASP.NET Core项目那么上面的env.IsDevelopment()就会返回true,如果你发布(publish)了ASP.NET Core项目,并在IIS中运行发布后的项目代码,那么上面的env.IsDevelopment()就会返回false。

env.IsDevelopment()其实是IHostingEnvironment接口(IHostingEnvironment接口默认就注册在了ASP.NET Core的依赖注入容器中,可以在ASP.NET Core中任何需要用依赖注入的地方<例如,Startup类的构造函数(由于IHostingEnvironment接口默认就在ASP.NET Core的依赖注入容器中,所以在Startup类的构造函数中ASP.NET Core就可以注入IHostingEnvironment接口),Startup类的Configure方法,Controller的构造函数,中间件,MVC视图等地方>使用IHostingEnvironment接口)的一个扩展方法,其定义在HostingEnvironmentExtensions这个扩展类中,可以看到HostingEnvironmentExtensions类定义了一些和ASP.NET Core运行环境相关的方法:

其中

  • IsDevelopment方法用来检测ASP.NET Core项目当前是否处于开发环境,比如在Visual Studio中运行ASP.NET Core项目IsDevelopment方法就会返回true
  • IsProduction方法用来检测ASP.NET Core项目当前是否处于生产环境,比如将ASP.NET Core项目发布(publish)后,IsProduction方法就会返回true
  • IsStaging方法用来检测ASP.NET Core项目当前是否处于一个中间环境,比如如果项目还有测试环境,就可以将IsStaging方法用来检测ASP.NET Core项目是否处于测试环境

那么为什么在Visual Studio中运行ASP.NET Core项目,HostingEnvironmentExtensions类的IsDevelopment方法会返回true呢?我们打开ASP.NET Core项目Properties节点下的launchSettings.json文件

其中的Json文本如下:

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

我们可以看到在"profiles"下有一个"IIS Express"节点,其中有一个"ASPNETCORE_ENVIRONMENT"属性,其值为Development,这就表示了当我们在Visual Studio中用IIS Express运行ASP.NET Core项目时,处于的是Development环境,所以此时HostingEnvironmentExtensions类的IsDevelopment方法会返回true。ASPNETCORE_ENVIRONMENT属性后面可以定义任何值,但是一般来说都定义为Development、Production和Staging三个值,对应的HostingEnvironmentExtensions类的三个方法,如果你定义了一个其它的值(比如Staging2),可以用HostingEnvironmentExtensions类的IsEnvironment方法进行检测,参数environmentName就是要检测的环境名(比如Staging2)。当发布ASP.NET Core项目后,ASPNETCORE_ENVIRONMENT属性的默认值会是Production,这就是为什么当ASP.NET Core项目发布后,HostingEnvironmentExtensions类的IsProduction方法会返回true。

此外ASPNETCORE_ENVIRONMENT属性的值还可以影响ASP.NET Core项目appsettings文件的读取,我们来看下面一个例子:

假设我们有个ASP.NET Core MVC项目叫WebCoreEnvironments,其中我们定义了两套appsettings文件:appsettings.Development.json和appsettings.Production.json,分别用于存放项目开发环境和生产环境的参数, appsettings.Development.json和appsettings.Production.json中都定义了一个属性叫TestString,不过两个文件存储的TestString属性值不同。

appsettings.Development.json文件内容如下:

{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"AppSettings": {
"TestString": "This is development environment"
}
}

appsettings.Production.json文件内容如下:

{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"AppSettings": {
"TestString": "This is production environment"
}
}

当然可以在默认的appsettings.json文件中也定义TestString属性,当项目中appsettings.Development.json和appsettings.Production.json文件不存在的时候,或当在appsettings.Development.json和appsettings.Production.json文件中找不到TestString属性的时候,就会采用默认的appsettings.json文件的内容。appsettings.json文件内容如下:

{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AppSettings": {
"TestString": "This is default environment"
},
"AllowedHosts": "*"
}

接着我们在ASP.NET Core MVC项目中定义了一个AppSettings类用于读取和反序列化appsettings文件的内容:

namespace WebCoreEnvironments.Models
{
public class AppSettings
{
public string TestString { get; set; }
}
}

其中就一个TestString属性和appsettings文件中的属性同名。

然后我们在Startup类中设置读取appsettings文件的代码,其中相关代码用黄色高亮标记了出来:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebCoreEnvironments.Models; namespace WebCoreEnvironments
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)//这里采用appsettings.{env.EnvironmentName}.json根据当前的运行环境来加载相应的appsettings文件
.AddEnvironmentVariables(); Configuration = builder.Build();
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
}); services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles();
app.UseCookiePolicy(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

可以看到我们在读取appsettings文件时,使用了AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)来根据当前ASP.NET Core项目所处的环境读取相应的appsettings文件,如果是开发环境就读取appsettings.Development.json,如果是生产环境就读取appsettings.Production.json。

注意上面Startup构造函数中黄色高亮代码的调用顺序,会产生如下效果:

  • 首先,我们调用了AddJsonFile("appsettings.json", optional: true, reloadOnChange: true),来加载默认的appsettings.json文件中的内容。
  • 然后,我们调用了AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true),根据当前的运行环境来加载相应的appsettings文件的内容,因为AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)放在了AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)的后面,所以在"appsettings.json"文件中属性"TestString"的值,会被"appsettings.{env.EnvironmentName}.json"文件中属性"TestString"的值覆盖,这是因为"appsettings.{env.EnvironmentName}.json"文件在"appsettings.json"文件之后加载,所以"appsettings.{env.EnvironmentName}.json"文件会覆盖"appsettings.json"文件中同名的属性(但是在"appsettings.json"文件中有,而在"appsettings.{env.EnvironmentName}.json"文件中没有的属性,不会被覆盖)。
  • 此外由于AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)的参数optional为true,所以如果当前运行环境对应的"appsettings.{env.EnvironmentName}.json"文件在ASP.NET Core项目中不存在,也不会导致AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)方法抛出异常,但是如果optional参数为false,AddJsonFile方法找不到文件就会抛出异常。
  • 最后,我们调用了AddEnvironmentVariables(),来加载操作系统中环境变量的值,由于AddEnvironmentVariables方法在最后,所以环境变量会覆盖与"appsettings.json"和"appsettings.{env.EnvironmentName}.json"文件中同名的属性。

所以最后ASP.NET Core中包含的是 "appsettings.json"、"appsettings.{env.EnvironmentName}.json"、"操作系统环境变量" 中属性名去重后的并集。

然后我们在Index.cshtml视图文件(对应HomeController的Index方法)中定义了如下代码:

@{
Layout = null;
} @using Microsoft.AspNetCore.Hosting
@using Microsoft.Extensions.Options;
@using WebCoreEnvironments.Models @inject IHostingEnvironment env
@inject IOptions<AppSettings> appSettings
<!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
Current environment is:@env.EnvironmentName
</div>
<div>
Is this a development environment:@env.IsDevelopment().ToString()
</div>
<div>
Is this a production environment:@env.IsProduction().ToString()
</div>
<div>
TestString in AppSettings is :@appSettings.Value.TestString
</div>
</body>
</html>

在Index.cshtml视图中我们使用@inject标签,让ASP.NET Core MVC依赖注入了IHostingEnvironment接口变量env和IOptions<AppSettings>接口变量appSettings,分别用于读取当前ASP.NET Core项目所处的环境和appsettings文件的内容。

接着我们用env.EnvironmentName、env.IsDevelopment和env.IsProduction来检测当前ASP.NET Core项目所处的环境

然后我们用appSettings.Value.TestString输出当前环境对应的appsettings文件中,TestString属性的值。

当我们在Visual Studio中运行项目时,访问Index.cshtml视图,浏览器结果如下:

可以看到当前所处的环境是Development,所以env.IsDevelopment返回true,env.IsProduction返回false,并且appSettings.Value.TestString的值为我们在appsettings.Development.json文件中定义的内容。

现在我们发布ASP.NET Core项目到一个叫publish的windows文件夹,然后将其部署到IIS中的一个站点上:

我们现在访问IIS站点中的Index.cshtml视图,浏览器结果如下:

可以看到当前所处的环境是Production,所以env.IsDevelopment返回false,env.IsProduction返回true,并且appSettings.Value.TestString的值为我们在appsettings.Production.json文件中定义的内容。

现在我们发现当我们发布ASP.NET Core项目后,其ASPNETCORE_ENVIRONMENT属性的值始终是Production,所以发布ASP.NET Core项目后其处于Production环境。那么有没有办法将发布后的ASP.NET Core项目改为Staging环境(比如需要部署到测试环境服务器)呢?

这时我们可以从ASP.NET Core项目发布后的文件夹中找到web.config文件:

将其打开后可以看到其中有一个aspNetCore的XML节点如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\WebCoreEnvironments.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: b9c7e11d-171e-41c4-b7aa-3c0225f76647-->

将其改为如下,然后再放到IIS的站点目录下,现在ASP.NET Core项目就处于Staging环境了:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\WebCoreEnvironments.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" >
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: b9c7e11d-171e-41c4-b7aa-3c0225f76647-->

注意,上面arguments=".\WebCoreEnvironments.dll"属性为你的ASP.NET Core项目程序集dll文件名。

如何不修改ASP.NET Core项目Startup类的构造函数

我们看到上面的代码中,我们有修改ASP.NET Core项目中Startup类的构造函数,从ASP.NET Core 2.0开始,我们可以不修改项目的Startup类构造函数,例如我们也可以采用新建ASP.NET Core 2.0项目时Startup类的默认构造函数:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebCoreEnvironments.Models; namespace WebCoreEnvironments
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
}); services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles();
app.UseCookiePolicy(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

但是我们要修改ASP.NET Core项目中Program类(在ASP.NET Core项目中的Program.cs文件中)的代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; namespace WebCoreEnvironments
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
} public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((webHostBuilderContext, configurationbuilder) =>
{
var env = webHostBuilderContext.HostingEnvironment;//可以通过WebHostBuilderContext类的HostingEnvironment属性得到IHostingEnvironment接口对象 configurationbuilder.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)//这里采用appsettings.{env.EnvironmentName}.json根据当前的运行环境来加载相应的appsettings文件
.AddEnvironmentVariables();
})
.UseStartup<Startup>();
}
}

可以看到其实我们就是将ASP.NET Core项目Startup类构造函数中配置读取appsettings文件的逻辑,移植到了ASP.NET Core项目中的Program类里面,其中可以通过WebHostBuilderContext类的HostingEnvironment属性得到IHostingEnvironment接口对象,来读取当前ASP.NET Core项目所处的运行环境是什么。

关于本文所述的内容,可以参考微软官方关于ASP.NET Core多环境配置的文档,链接如下:

Use multiple environments in ASP.NET Core

下载本文示例项目代码

转载自:https://www.cnblogs.com/opencoder/p/9827694.html

【转】ASP.NET Core 如何设置发布环境的更多相关文章

  1. ASP.NET Core 如何设置发布环境

    在ASP.NET Core中自带了一些内置对象,可以读取到当前程序处于什么样的环境当中,比如在ASP.NET Core的Startup类的Configure方法中,我们就会看到这么一段代码: publ ...

  2. 用"hosting.json"配置ASP.NET Core站点的Hosting环境

    通常我们在 Prgram.cs 中使用硬编码的方式配置 ASP.NET Core 站点的 Hosting 环境,最常用的就是 .UseUrls() . public class Program { p ...

  3. ASP.NET Core 新建项目 - macOS 环境 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 新建项目 - macOS 环境 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 新建项目 - macOS 环境 对于任何语言和 ...

  4. 《ASP.NET Core 高性能系列》环境(EnvironmentName)的设置

    一.概述 程序启动时Host捕获到环境相关数据,然后交由IEnvironment(传说要作废,但是觉得这个有设计点问题,因为.NET Core 非Web怎么处理?),然后交由IWebHostEnvir ...

  5. ASP.NET Core 快速入门(环境篇)

    [申明]:本人.NET Core小白.Linux小白.MySql小白.nginx小白.而今天要说是让你精通Linux ... 的开机与关机.nginx安装与部署.Core的Hello World .. ...

  6. 菜鸟入门【ASP.NET Core】1:环境安装

    下载.NET Core SDK 下载地址:https://www.microsoft.com/net/download/windows https://www.microsoft.com/net/le ...

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

    原文地址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-2.1#star ...

  8. 【转】ASP.NET Core 快速入门(环境篇)

    原文链接:http://www.cnblogs.com/zhaopei/p/netcore.html [申明]:本人.NET Core小白.Linux小白.MySql小白.nginx小白.而今天要说是 ...

  9. ASP.NET Core 2.0发布/部署到Ubuntu服务器并配置Nginx反向代理

    原文链接https://www.linuxidc.com/Linux/2017-12/149557.htm ASP.NET Core 2.0 怎么发布到Ubuntu服务器?又如何在服务器上配置使用AS ...

随机推荐

  1. alter对话框处理:

    from selenium import webdriverd = webdriver.Firefox()d.get('file://C:\\我的代码\\selenium自动化测试\\alter.ht ...

  2. Python函数(函数定义、函数调用)用法详解

    Python 中,函数的应用非常广泛,前面章节中我们已经接触过多个函数,比如 input() .print().range().len() 函数等等,这些都是 Python 的内置函数,可以直接使用. ...

  3. Jrebel实现tomcat热部署,遇到的问题以及解决办法,详解

    我的安装的详细过程: 下载Jrebel:  https://github.com/ilanyu/ReverseProxy/releases/tag/v1.4 我的是winx64,所以选择如下的: 下载 ...

  4. JS 实现动态轮播图

    JavaScript实现轮播图思路 + html/css + js源码 整个轮播图的效果是通过js代码,操作dom, 拿到html我们需要的元素,控制整个ul的距离浏览器左边的位置,让排好的图片依次出 ...

  5. Java中间消息件——ActiveMQ入门级运用

    先来说一说我们为什么要用这个东西啊! 比如,我们现在有这样了个问题要解决: 这样,我们就要用到中间消息间了 然后我们就说一下什么是中间消息间吧. 采用消息传送机制/消息队列 的中间件技术,进行数据交流 ...

  6. Difference between JDK, JRE and JVM

    With Java programming language, the three terms i.e. JDK, JRE and JVM will always be there to unders ...

  7. SpringCloud的入门学习之深入理解Eureka注册中心

    1.Eureka 注册中心三种角色. 答:a.Eureka Server,注册中心,通过 Register.Get.Renew 等接口提供服务的注册和发现. b.Application Service ...

  8. SpringBoot启动项目时提示:Error:(3, 32) java: 程序包org.springframework.boot不存在

    场景 在IDEA中新建SpringBoot项目,后启动项目时提示: Error:(3, 32) java: 程序包org.springframework.boot不存在 实现 将pom.xml中par ...

  9. 面试再问ThreadLocal,别说你不会

    转载自:公众号<Java知音> ThreadLocal是什么 以前面试的时候问到ThreadLocal总是一脸懵逼,只知道有这个哥们,不了解他是用来做什么的,更不清楚他的原理了.表面上看他 ...

  10. Eclipse 的快捷键

    1. 代码折叠的快捷键,默认是: Ctrl+Shift+Numpad_Divede(小键盘的/号) Ctrl+Shift+Numpad_Multiply(小键盘的*号) 2.删除一行:Ctrl+D 3 ...