如何在.NET Core MVC项目中转换AppSettings.json?

发布于 2025-02-12 05:23:04 字数 981 浏览 1 评论 0原文

我已经在项目中添加了其他JSON配置文件

appsettings.DEV.json
appsettings.QA.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, reloadOnChange: true);
    ...

并且我了解如何更改环境:修改aspnetcore_environment 项目属性中的环境变量。但是,似乎没有能力指定不同的环境变量,具体取决于配置,下拉列表被标记为“ n/a”并禁用。

我看到的唯一选项是手动更改环境变量值,以更改使用哪些应用程序。我敢肯定,有一种自动进行操作的方法,否则您将如何使用CI? (除了使用脚本更改环境变量之外,还必须有一种更简单的方法)。

这里的目标是为三种环境设置自动化构建和连续集成:dev,Qa和prod。 dev和qa在同一台计算机上,因此设置环境变量这不是手动指定环境的选择。

I've added additional json config files to my project

appsettings.DEV.json
appsettings.QA.json

and loaded them in the Startup function based on the environment:

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, reloadOnChange: true);
    ...

And I understand how to change the environment: modify the value of the ASPNETCORE_ENVIRONMENT environment variable in project properties. However, there does not appear to be the ability to specify different environment variables depending on the configuration, the dropdownlist is labeled "N/A" and disabled.

The only option I see is to manually change the environment variable value, to change which appsettings are used. I'm sure there is a way to do it automatically, or else how would you ever use CI? (other than using a script to change the environment variable, there has to be an easier way).

The goal here is to setup automated builds and continuous integration for three environments: DEV, QA, and PROD. DEV and QA are on the same machine, so setting the environment variable that specifies the environment manually is not an option.

Project Properties : Debug section

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我三岁 2025-02-19 05:23:04

从构建类型中确定

任何想基于构建类型设置环境名称的人的构建类型,有方便的.iaseEnvironment(emoventionName) on webhostbuilder(在Program Main中找到)。

只要针对项目中的构建配置设置了适当的编译符号,就可以执行类似的操作来确定环境名称:

public static void Main(string[] args)
{
    string environmentName;
#if DEBUG
    environmentName = "Development";
#elif STAGING
    environmentName = "Staging";
#elif RELEASE
    environmentName = "Production";
#endif

    var host = new WebHostBuilder()
        .UseKestrel()
        .UseEnvironment(environmentName)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseApplicationInsights()
        .Build();

    host.Run();
}

Determine EnvironmentName from Build Type

For anybody that would like to set the EnvironmentName based on the build type, there is the handy .UseEnvironment(environmentName) on WebHostBuilder (found in Program Main).

As long as the appropriate compilation symbols are set against the build configurations in your project, you can do something like this to determine the EnvironmentName:

public static void Main(string[] args)
{
    string environmentName;
#if DEBUG
    environmentName = "Development";
#elif STAGING
    environmentName = "Staging";
#elif RELEASE
    environmentName = "Production";
#endif

    var host = new WebHostBuilder()
        .UseKestrel()
        .UseEnvironment(environmentName)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseApplicationInsights()
        .Build();

    host.Run();
}
垂暮老矣 2025-02-19 05:23:04

如果您在program.cs中使用默认代码,则除了创建项目中的两个文件之外,您无需执行任何操作。

program.cs中的默认代码如下:

public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();

这是实际上在做的事情:

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
    var builder = new WebHostBuilder();

    ...

    builder.ConfigureAppConfiguration((hostingContext, config) =>
    {
        var env = hostingContext.HostingEnvironment;

        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
    });

    ...

    return builder;
}

env.environmentname设置为aspnetcore_environment环境变量的值要做的就是创建appsettings。{aspnetcore_environment} .json文件,它将自动合并。

附加注意:要使两个文件实际合并,请使用此语法:

var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();

不:

var appSettings = new AppSettings();
Configuration.Bind("AppSettings", appSettings);
return appSettings;

后者不会返回合并的数据。

感谢Shawn Wildermuth的 this

If you are using the default code in Program.cs, you don't need to do anything beyond creating the two files in the project.

The default code in Program.cs looks like this:

public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();

Here's what that's actually doing:

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
    var builder = new WebHostBuilder();

    ...

    builder.ConfigureAppConfiguration((hostingContext, config) =>
    {
        var env = hostingContext.HostingEnvironment;

        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
    });

    ...

    return builder;
}

env.EnvironmentName is set to the value of the ASPNETCORE_ENVIRONMENT environment variable, so all you have to do is create the appsettings.{ASPNETCORE_ENVIRONMENT}.json file and it will automatically get merged.

Additional note: to get the two files to actually merge, use this syntax:

var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();

not:

var appSettings = new AppSettings();
Configuration.Bind("AppSettings", appSettings);
return appSettings;

The latter will not returned the merged data.

Thanks to Shawn Wildermuth for this.

萌面超妹 2025-02-19 05:23:04

我找到了Tsengs回答的解决方案,但希望在这里描述它。
解决方案是在另一个问题的答案中找到的,但是这个问题完全不同(我也扩展了答案),因此我不认为这个问题应该被标记为重复。

答案是

” 的每个IIS网站上的值

aspnetcore_environment 这样做是:

  1. 转到IIS中的应用程序,然后选择配置编辑
  2. 选择配置编辑器
  3. 选择system.webserver/aspnetcore(rc2 and rtm)或system.webserver/httpplatform(rc1(rc1)) /code> combobox
  4. 选择applicationhost.config ...在 combobox中中。
  5. 单击EnviroMentVariables元素,然后打开编辑窗口。
  6. 设置您的环境变量。
  7. 关闭窗口,然后单击“应用”。
  8. 另外

,您可以修改applicationhost.config file(通常位于c:\ windows \ system32 \ inetsrv \ inetsrv \ config \ applicationhost.config

,并在下面添加以下条目root &lt; configuration&gt;标签,其中“ my-iis site”是IIS网站的名称。

<location path="my-iis-site">
    <system.webServer>
        <aspNetCore>
            <environmentVariables>
                <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="DEV" />
            </environmentVariables>
        </aspNetCore>
    </system.webServer>
</location>

I've found a solution from Tsengs answer but wish to describe it here for clarity.
The solution is found in the answer to another question however the question is quite different (and I've also expanded upon the answer) so I do not believe this question should be marked as a duplicate.

The answer is here

The solution is to setup different environment variable values on each IIS site for the key ASPNETCORE_ENVIRONMENT

The steps to do so are:

  1. Go to your application in IIS and choose Configuration Editor.
  2. Select Configuration Editor
  3. Choose system.webServer/aspNetCore (RC2 and RTM) or system.webServer/httpPlatform (RC1) in Section combobox
  4. Choose Applicationhost.config ... in From combobox.
  5. Click on enviromentVariables element and open edit window.
  6. Set your environment variables.
  7. Close the window and click Apply.
  8. Done

Alternatively, you can modify your applicationHost.config file (normally located at C:\Windows\System32\inetsrv\config\applicationHost.config

And add the following entry under the root <Configuration> tag, where "my-iis-site" is the name of your IIS site.

<location path="my-iis-site">
    <system.webServer>
        <aspNetCore>
            <environmentVariables>
                <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="DEV" />
            </environmentVariables>
        </aspNetCore>
    </system.webServer>
</location>
酒浓于脸红 2025-02-19 05:23:04

您在图片中链接的对话框仅是为了配置“ lainingsettings.json”。此文件是您的应用程序未使用的

当您击中F5时,Visual Studio仅使用Visual Studio来设置环境并在浏览器中打开一个URL。

当您要切换环境时,您需要在启动之前设置环境变量。如何做到这一点,取决于您的环境。

Windows(CommandLine,CMD.EXE)

setx ASPNETCORE_ENVIRONMENT "Development"

Windows(PowerShell)

$Env:ASPNETCORE_ENVIRONMENT = "Development"

Linux

export ASPNETCORE_ENVIRONMENT="Development"

Linux(将其设置为单个命令)

ASPNETCORE_ENVIRONMENT="Development" dotnet run

在注释中更新是在注释中

它是机器特定的(Linux除外,您可以每次命令进行操作)。但是,在IIS中,您也可以通过不同的应用程序池或遵循这个答案

The dialog you linked in the picture is only to configure "launchSettings.json". This file is not used by your application.

It is only used by Visual Studio to set the environment and open an URL in the browser when you hit F5 and nothing else.

When you want to switch environments, you need to setup an environment variable before launching. How to do this, depends on your environment.

Windows (Commandline, cmd.exe)

setx ASPNETCORE_ENVIRONMENT "Development"

Windows (Powershell)

$Env:ASPNETCORE_ENVIRONMENT = "Development"

Linux

export ASPNETCORE_ENVIRONMENT="Development"

Linux (Set it for a single command)

ASPNETCORE_ENVIRONMENT="Development" dotnet run

Update in regards to the comment

Yes it is machine specific (except for Linux, which you can do per command). However, in IIS you can do that too either via different app pools or by following this answers instructions to add it to IIS

旧情勿念 2025-02-19 05:23:04

如果您使用的是Azure添加Aspnetcore_environment,则在WebApp旁边的应用程序设置相应的值,然后将选择正确的AppSettings。{value} .json File

If you are using azure add ASPNETCORE_ENVIRONMENT with corresponding value to Application Settings in side of webapp, which will then pick up correct appsettings.{value}.json file

咆哮 2025-02-19 05:23:04

我们正在使用以下appsettings.json文件:

appsettings.json
appsettings.Community.json

由于我们使用的是Blazor WebAssembly我们在服务器项目 client wwwroot中都有这些文件。为了使转换在Azure应用服务中进行,我们在配置中设置了一个应用程序设置,该设置将aspnetcore_environment设置为code> community

要在可以通过依赖项注入代码使用的类中获取appSettings.json,如下所示:

appsettings.json:

{
  "UiBaseUrl": "https://example.com",
  "JiraIntegrationSettings": {
    "UseJira": false,
    }
}

appsettings.cs:

public class AppSettings
{
    public string UiBaseUrl { get; set; }

    public JiraIntegrationSettings JiraIntegrationSettings { get; set; }
}

public class JiraIntegrationSettings
{
    public bool UseJira { get; set; }
    
}

streetup.cs: startup.cs:program.cs:program.cs:

var settings = new AppSettings();
Configuration.Bind(settings);
services.AddSingleton(settings);

program.cs :

var settings = new ClientAppSettings();
builder.Configuration.Bind(settings);
builder.Services.AddSingleton(settings);

然后可以将其注入任何类别或控制器,例如此示例:

public ProductsController(ExtendedApplicationDbContext extendedApplicationDbContext, AppSettings settings, ILogger<ProductsController> logger)
{
    _extendedApplicationDbContext = extendedApplicationDbContext;
    _settings = settings;
    _logger = logger;
}

大火前端注射看起来像这样:

@inject ClientAppSettings ClientAppSettings

We are using the following appsettings.json files:

appsettings.json
appsettings.Community.json

Since we are using Blazor WebAssembly we have these files both in the Server project and Client wwwroot. In order for the transformation to take place in Azure App Service we have a Application Setting under Configuration that sets ASPNETCORE_ENVIRONMENT to Community.

enter image description here

To get appsettings.json in a Class that can be used via dependency injection code looks like this:

appsettings.json:

{
  "UiBaseUrl": "https://example.com",
  "JiraIntegrationSettings": {
    "UseJira": false,
    }
}

AppSettings.cs:

public class AppSettings
{
    public string UiBaseUrl { get; set; }

    public JiraIntegrationSettings JiraIntegrationSettings { get; set; }
}

public class JiraIntegrationSettings
{
    public bool UseJira { get; set; }
    
}

Startup.cs:

var settings = new AppSettings();
Configuration.Bind(settings);
services.AddSingleton(settings);

Program.cs:

var settings = new ClientAppSettings();
builder.Configuration.Bind(settings);
builder.Services.AddSingleton(settings);

This can then be injected into any class or Controller like this example:

public ProductsController(ExtendedApplicationDbContext extendedApplicationDbContext, AppSettings settings, ILogger<ProductsController> logger)
{
    _extendedApplicationDbContext = extendedApplicationDbContext;
    _settings = settings;
    _logger = logger;
}

Blazor front end injection looks like this:

@inject ClientAppSettings ClientAppSettings
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文