为asp.net核心中的开发和发布环境自动设置appsettings.json?
Posted
技术标签:
【中文标题】为asp.net核心中的开发和发布环境自动设置appsettings.json?【英文标题】:Automatically set appsettings.json for dev and release environments in asp.net core? 【发布时间】:2018-03-04 00:11:42 【问题描述】:我在appsettings.json
中为数据库连接字符串、webapi 位置等定义了一些值,这些值对于开发、暂存和实时环境是不同的。
有没有办法拥有多个appsettings.json
文件(如appsettings.live.json
等)并让asp.net 应用程序根据其运行的构建配置“知道”使用哪个文件?
【问题讨论】:
【参考方案1】:当我使用没有网页的控制台应用程序时,这是适用于我的版本:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT").json", optional: true);
IConfigurationRoot configuration = builder.Build();
AppSettings appSettings = new AppSettings();
configuration.GetSection("AppSettings").Bind(appSettings);
【讨论】:
【参考方案2】:.vscode/launch.json 文件仅由 Visual Studio 以及 /Properties/launchSettings.json 文件使用。不要在生产中使用这些文件。
launchSettings.json 文件:
-
仅在本地开发机器上使用。
未部署。
包含配置文件设置。
launchSettings.json 中设置的环境值覆盖系统环境中设置的值以使用文件“appSettings.QA.json”为例。您可以使用“ASPNETCORE_ENVIRONMENT”。请按照以下步骤操作。
-
在主机上添加一个新的环境变量并将其命名为“ASPNETCORE_ENVIRONMENT”。将其值设置为“QA”。
在您的项目中创建一个文件“appSettings.QA.json”。在此处添加您的配置。
在步骤 1 中部署到机器。确认已部署“appSettings.QA.json”。
加载您的网站。预计 appSettings.QA.json 将在此处使用。
【讨论】:
这是否意味着,如果您有 5 个环境和 5 个 appsettings.EnvName.json 文件,所有这些都将被部署并且只有一台选定的机器,因为构建定义的工件将包含所有 5 个文件?或者只应该部署 appsettings.json(作为主要)+ appsettings.CurrentEnvironment.json(作为覆盖)以及如何部署?【参考方案3】:.NET Core 3.0+ 更新
您可以使用CreateDefaultBuilder
,它会自动构建配置对象并将其传递给您的启动类:
WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
public class Startup
public Startup(IConfiguration configuration) // automatically injected
Configuration = configuration;
public IConfiguration Configuration get;
/* ... */
CreateDefaultBuilder
自动包含适当的 appsettings.<i>Environment</i>.json
文件,因此为每个环境添加单独的 appsettings 文件:
然后在运行/调试时设置ASPNETCORE_ENVIRONMENT
环境变量
如何设置环境变量
根据您的 IDE,dotnet 项目通常会在几个地方查找环境变量:
对于 Visual Studio,请转到项目 > 属性 > 调试 > 环境变量:
对于 Visual Studio 代码,编辑 .vscode/launch.json
> env
:
使用启动设置,编辑Properties/launchSettings.json
> environmentVariables
:
也可以从 Visual Studio 的工具栏中选择
使用 dotnet CLI,为 setting environment variables per your OS 使用适当的语法
注意:当使用dotnet run 启动应用程序时,会读取
launchSettings.json
(如果可用),并且launchSettings.json 中的environmentVariables
设置会覆盖环境变量。
Host.CreateDefaultBuilder
是如何工作的?
.NET Core 3.0 在平台扩展下添加了Host.CreateDefaultBuilder
,它将提供IConfiguration
的默认初始化,它按以下顺序为应用提供默认配置:
appsettings.json
使用 JSON configuration provider。appsettings.<i>Environment</i>.json
使用 JSON configuration provider。例如:appsettings.<i>Production</i>.json
或appsettings.<i>Development</i>.json
App secrets 当应用在开发环境中运行时。 环境变量使用Environment Variables configuration provider。 命令行参数使用Command-line configuration provider。
进一步阅读 - MS Docs
App startup in ASP.NET Core Configuration in ASP.NET Core Use multiple environments in ASP.NET Core【讨论】:
谢谢,很好,但是如何使用控制台进程(或工作进程模板/脚手架)来做到这一点? 这不适用于最新版本,它将始终采用 appsettings.json 并忽略 appsettings.development.json。 Run (dev) 和 run (prod) 也不见了。 这应该是公认的答案。【参考方案4】:在 ASP.NET Core 中,您应该使用环境变量而不是构建配置以获得正确的 appsettings.json
右键单击您的项目>属性>调试>环境变量
ASP.NET Core 将使用适当的 appsettings.json 文件:
现在您可以像这样使用该环境变量:
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)
.AddEnvironmentVariables();
Configuration = builder.Build();
注意:如果您使用@Dmitry's answer,您可能会遇到问题,例如。 在 Azure 上覆盖 appsettings.json 值时。
【讨论】:
【参考方案5】:我添加了工作环境的屏幕截图,因为它花费了我几个小时的研发时间。
首先,在您的launch.json
文件中添加一个密钥。
请看下面的截图,我已经添加了 Development
作为我的环境。
然后,在您的项目中,创建一个包含环境名称的新 appsettings.environment.json
文件。
在以下屏幕截图中,查找两个具有不同名称的文件:
appsettings.Development.Json
appSetting.json
最后,将它配置到您的 StartUp
类中,如下所示:
public Startup(IHostingEnvironment env)
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
最后,你可以像这样从命令行运行它:
dotnet run --environment "Development"
其中 "Development"
是我的环境的名称。
【讨论】:
试过了,效果很好。 VS2017 甚至在基础文件下显示不同的版本。赞成票。 当 ihostingenvironment 被弃用时,你如何在 core 2.2 中做到这一点 @djack109 你应该改用IWebHostEnvironment
。【参考方案6】:
创建多个appSettings.<i>$(Configuration)</i>.json
文件,例如:
appSettings.staging.json
appSettings.production.json
在项目上创建一个预构建事件,将相应的文件复制到appSettings.json
:
copy appSettings.$(Configuration).json appSettings.json
在您的配置生成器中仅使用 appSettings.json
:
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
【讨论】:
这应该是一个可以接受的答案。复杂情况可以使用SlowCheetah。 如何在项目上创建预构建事件?该行的起始副本应该放在哪里......实际上应该放在哪里? @Paul 在 Visual Studio 中,右键单击解决方案资源管理器视图中的项目,从右键菜单中选择Properties
,然后在属性视图中选择 Build Events
。【参考方案7】:
您可以在launchSettings.json
中添加配置名称为ASPNETCORE_ENVIRONMENT
,如下所示
"iisSettings":
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress":
"applicationUrl": "http://localhost:58446/",
"sslPort": 0
,
"profiles":
"IIS Express":
"commandName": "IISExpress",
"environmentVariables":
ASPNETCORE_ENVIRONMENT": "$(Configuration)"
【讨论】:
【参考方案8】:你可以使用条件编译:
public Startup(IHostingEnvironment env)
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#if SOME_BUILD_FLAG_A
.AddJsonFile($"appsettings.flag_a.json", optional: true)
#else
.AddJsonFile($"appsettings.no_flag_a.json", optional: true)
#endif
.AddEnvironmentVariables();
this.configuration = builder.Build();
【讨论】:
您应该在 MSBuild/TFS 构建中设置环境变量。条件编译会导致 CI 构建中容易处理的错误。即 .AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true) 环境变量见我的回答 (***.com/a/50331886/1319086) 这种方法强制为每个环境专门重新编译代码,使其无法重新分发/安装到其他地方。 问题是关于“了解构建配置” 这不应被标记为已接受的答案 - 尽管这是一个解决方案,但它不是最佳实践。【参考方案9】:只是针对.NET core 2.0用户的更新,可以在调用CreateDefaultBuilder
后指定应用配置:
public class Program
public static void Main(string[] args)
BuildWebHost(args).Run();
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(ConfigConfiguration)
.UseStartup<Startup>()
.Build();
static void ConfigConfiguration(WebHostBuilderContext ctx, IConfigurationBuilder config)
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("config.json", optional: false, reloadOnChange: true)
.AddJsonFile($"config.ctx.HostingEnvironment.EnvironmentName.json", optional: true, reloadOnChange: true);
【讨论】:
如何在使用的环境之间切换?是否应该在任何配置文件中进行更改?我知道我需要将项目在 Azure 上运行时要使用的 URL 添加到 appsettings.json 并将本地运行时要执行的 URL(按 F5)添加到 appsettings.Development.json。那是对的吗?我要使用的字符串在文件 launchSettings.json 中,我有点不清楚如何根据应用程序的执行位置(或者是否应该在全部)。 @DonkeyBanana 环境只不过是项目属性中指定的设置。在 VS 2017 中,右键单击项目 > 属性。在调试下,您将看到密钥ASPNETCORE_ENVIRONMENT
的当前环境。该值将替换为ctx.HostingEnvironment.EnvironmentName
。因此,如果您在属性中将该值设置为“生产”,项目将在根文件夹中查找config.Production.json
文件。欲了解更多信息,请查看此link
在 WebHost.CreateDefaultBuiler(... 中创建一个Error CS0266 Cannot implicitly convert type 'Microsoft.AspNetCore.Hosting.IWebHost' to 'Microsoft.AspNetCore.Hosting.IWebHostBuilder'. An explicit conversion exists (are you missing a cast?)
值得注意的是,here 指出“当您使用 CreateDefaultBuilder 初始化新的主机构建器时,会自动调用两次 AddJsonFile”。换句话说,它已经在加载 appSettings.json,然后根据您的环境配置,它正在加载 appsettings.Environment.json
@umutsen 在最新的 Visual Studio 中没有更多的运行环境设置【参考方案10】:
您可以像这样在Startup
构造函数中使用环境变量和ConfigurationBuilder
类:
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)
.AddEnvironmentVariables();
this.configuration = builder.Build();
然后您为您需要的每个环境创建一个appsettings.xxx.json
文件,其中“xxx”是环境名称。请注意,您可以将所有全局配置值放入“普通”appsettings.json
文件中,并且仅将环境特定的内容放入这些新文件中。
现在您只需要一个名为ASPNETCORE_ENVIRONMENT
的环境变量,并带有一些特定的环境值(“live”、“staging”、“production”等)。您可以在开发环境的项目设置中指定此变量,当然您还需要在暂存和生产环境中进行设置。你在那里做的方式取决于这是什么样的环境。
更新:我刚刚意识到您想根据您当前的构建配置选择appsettings.xxx.json
。我提出的解决方案无法实现这一点,我不知道是否有办法做到这一点。然而,“环境变量”方式是可行的,并且可能是您的方法的一个很好的替代方案。
【讨论】:
我在项目属性->调试部分中查看了使用环境变量,但是没有明显的方法将如何根据项目设置进行更改。那是我可以添加到我的项目中来处理它的另一个文件吗? 在项目属性中设置变量仅适用于在您的开发环境(可能是 Visual Studio)中使用它。您需要根据特定环境(IIS、Azure)为您部署的应用程序在其他地方设置它。我不建议在某个配置文件中设置该变量,因为该文件也可能被部署,然后覆盖服务器值。 您在构建配置中设置它。如果没有构建配置文件,那么他们是手动进行的,因此他们需要在(过时的)部署配置文件中进行设置 我在 Azure 中有多个环境,例如测试、登台和生产。如果我想将 Web 应用的发布版本从 VS 发布到 Azure,我应该在哪里更改 ASPNETCORE_ENVIRONMENT 变量? 我们在部署过程中不会更改变量,而是内置在特定环境中。在 Azure 中,您可以直接在“应用程序设置”下的应用服务配置中设置这些值。如果您使用多个插槽,请不要忘记将它们标记为“部署插槽设置”。以上是关于为asp.net核心中的开发和发布环境自动设置appsettings.json?的主要内容,如果未能解决你的问题,请参考以下文章
为测试人员存档时,如何将 .entitlements 中的“APS 环境”值设置为“开发”?