Definir appsettings.json automaticamente para ambientes de desenvolvimento e lançamento no núcleo do asp.net?

105

Eu defini alguns valores em meu appsettings.jsonpara coisas como strings de conexão de banco de dados, localizações de webapi e outros que são diferentes para ambientes de desenvolvimento, teste e ao vivo.

Existe uma maneira de ter vários appsettings.jsonarquivos (como appsettings.live.jsonetc, etc) e fazer com que o aplicativo asp.net apenas 'saiba' qual usar com base na configuração de compilação que está executando?

remédios
fonte

Respostas:

31

Você pode usar compilação condicional:

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();
}
Dmitry
fonte
28
Você deve definir a variável de ambiente em sua compilação MSBuild / TFS. A compilação condicional leva a erros para algo facilmente manipulado em compilações de CI. Ou seja, .AddJsonFile ($ "appsettings. {Env.EnvironmentName} .json", opcional: true)
Nick Turner
1
Veja minha resposta ( stackoverflow.com/a/50331886/1319086 ) para a variável de ambiente
Jonatan Dragon
10
Esse tipo de abordagem força a recompilação do código especificamente para cada ambiente, impossibilitando sua redistribuição / instalação em outro lugar.
tvdias
2
A pergunta era sobre “saber sobre a configuração de compilação”
Dmitry
6
Isso não deve ser marcado como a resposta aceita - embora seja uma solução, não é uma prática recomendada.
Charleh
98

Adicionei capturas de tela de um ambiente de trabalho, porque me custou várias horas de P&D.

  1. Primeiro, adicione uma chave ao seu launch.jsonarquivo.

    Veja a imagem abaixo, eu adicionei Developmentcomo meu ambiente.

    Declaração da variável de ambiente em launch.json

  2. Então, em seu projeto, crie um novo appsettings.{environment}.jsonarquivo que inclua o nome do ambiente.

    Na captura de tela a seguir, procure dois arquivos diferentes com os nomes:

    • appsettings.Development.Json
    • appSetting.json


    Visualização do projeto de arquivos JSON appsettings

  3. E, finalmente, configure-o para sua StartUpclasse assim:

    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();
    }
    
  4. E, por fim, você pode executá-lo a partir da linha de comando assim:

    dotnet run --environment "Development"
    

    onde "Development"está o nome do meu ambiente.

Bharat
fonte
2
Tentei isso e funciona muito bem. O VS2017 exibe até mesmo as diferentes versões no arquivo base. voto positivo.
Roberto
1
como fazer isso no núcleo 2.2 quando o ihostingenvironment está desativado
djack109
2
@ djack109 você deve usar no IWebHostEnvironmentlugar.
alessandrocb
70

Atualização para .NET Core 3.0+

  1. Você pode usar o CreateDefaultBuilderqual criará e passará automaticamente um objeto de configuração para sua classe de inicialização:

    WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
    
    public class Startup
    {
        public Startup(IConfiguration configuration) // automatically injected
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        /* ... */
    }
    
  2. CreateDefaultBuilderinclui automaticamente o arquivo apropriado, portanto, adicione um arquivo appsettings separado para cada ambiente:appsettings.Environment.json

    appsettings.env.json

  3. Em seguida, defina a ASPNETCORE_ENVIRONMENT variável de ambiente ao executar / depurar

Como definir variáveis ​​de ambiente

Dependendo do seu IDE, há alguns lugares onde os projetos dotnet tradicionalmente procuram por variáveis ​​de ambiente:

  • Para Visual Studio vá para Projeto> Propriedades> Depurar> Variáveis ​​de Ambiente:

    Visual Studio - Variáveis ​​de Ambiente

  • Para Visual Studio Code , edite .vscode/launch.json> env:

    Código do Visual Studio> Ambiente de inicialização

  • Usando as configurações de inicialização , edite Properties/launchSettings.json> environmentVariables:

    Configurações de inicialização

    Que também pode ser selecionado na barra de ferramentas do Visual Studio

    Lista suspensa de configurações de inicialização

  • Usando o dotnet CLI , use a sintaxe apropriada para definir as variáveis ​​de ambiente de acordo com o seu sistema operacional

    Nota : Quando um aplicativo é iniciado com a execução do dotnet , launchSettings.jsoné lido se disponível e as environmentVariablesconfigurações em launchSettings.json substituem as variáveis ​​de ambiente.

Como Host.CreateDefaultBuilderfunciona?

.NET Core 3.0 adicionado Host.CreateDefaultBuilderem extensões de plataforma que fornecerá uma inicialização padrão IConfigurationque fornece configuração padrão para o aplicativo na seguinte ordem:

  1. appsettings.jsonusando o provedor de configuração JSON .
  2. appsettings.Environment.jsonusando o provedor de configuração JSON . Por exemplo:
    • appsettings.Production.json ou
    • appsettings.Development.json
  3. Segredos do aplicativo quando o aplicativo é executado no ambiente de desenvolvimento.
  4. Variáveis ​​de ambiente usando o provedor de configuração Variáveis ​​de ambiente .
  5. Argumentos de linha de comando usando o provedor de configuração de linha de comando .

Leitura Adicional - MS Docs

KyleMit
fonte
Obrigado, é bom, mas como fazer isso com o processo de console (ou template / scaffolding de processo de trabalho)?
hB0
Isso não funciona com a versão mais recente, sempre pegará appsettings.json e ignorará appsettings.development.json. Run (dev) e run (prod) também estão faltando.
user1034912
45

No ASP.NET Core, você deve usar variáveis ​​de ambiente em vez da configuração de compilação para appsettings.json adequados

  1. Clique com o botão direito em seu projeto> Propriedades> Depurar> Variáveis ​​de Ambiente

    variáveis ​​ambientais

  2. O ASP.NET Core usará o arquivo appsettings.json apropriado:

    exemplo de arquivos appsettings no gerenciador de soluções

  3. Agora você pode usar essa variável de ambiente assim:

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

Nota : Se você usar a resposta de @Dmitry , poderá ter problemas, por exemplo. ao substituir os valores de appsettings.json no Azure.

Dragão Jonatan
fonte
35

Você pode usar as variáveis ​​de ambiente e a ConfigurationBuilderclasse em seu Startupconstrutor desta forma:

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

Em seguida, você cria um appsettings.xxx.jsonarquivo para cada ambiente de que precisa, com "xxx" sendo o nome do ambiente. Observe que você pode colocar todos os valores de configuração global em seu appsettings.jsonarquivo "normal" e apenas colocar as coisas específicas do ambiente nesses novos arquivos.

Agora você só precisa de uma variável de ambiente chamada ASPNETCORE_ENVIRONMENTcom algum valor de ambiente específico ("live", "staging", "production", qualquer que seja). Você pode especificar essa variável nas configurações do projeto para o seu ambiente de desenvolvimento e, é claro, também precisa defini-la nos ambientes de teste e produção. A maneira como você faz isso depende de que tipo de ambiente é esse.

ATUALIZAÇÃO: Acabei de perceber que você deseja escolher o com appsettings.xxx.jsonbase em sua configuração de compilação atual . Isso não pode ser alcançado com a minha solução proposta e não sei se existe uma maneira de fazer isso. A forma de "variável de ambiente", entretanto, funciona e pode também ser uma boa alternativa para sua abordagem.

Onkel Toob
fonte
Eu examinei o uso de variáveis ​​de ambiente, nas propriedades do projeto-> seção de depuração, no entanto, não há uma maneira óbvia de como isso vai mudar com base nas configurações do projeto. É outro arquivo que posso adicionar ao meu projeto para lidar com isso?
meds de
Definir a variável nas propriedades do projeto funcionará apenas para usá-la em seu ambiente de desenvolvimento (provavelmente Visual Studio). Você precisará configurá-lo em outro lugar para seus aplicativos implantados, dependendo do ambiente específico (IIS, Azure). Eu não recomendaria definir a variável em algum arquivo de configuração porque esse arquivo também pode ser implantado e, em seguida, substituir os valores do servidor.
Onkel Toob
Você o define nas configurações de compilação. Se não houver um arquivo de configuração de compilação, eles estão fazendo isso manualmente, portanto, precisariam configurá-lo no perfil de implantação (arcaico)
Nick Turner
Tenho vários ambientes como teste, preparação e produção no Azure. Onde eu altero a variável ASPNETCORE_ENVIRONMENT se eu quiser publicar a versão do aplicativo Web do VS para o Azure?
gelado de
Não alteramos as variáveis ​​durante a implantação; em vez disso, elas são integradas ao ambiente específico. No Azure, você pode definir esses valores diretamente na configuração do serviço de aplicativo em "Configurações do aplicativo". Não se esqueça de marcá-los como "Configurações de slot de implantação" caso esteja trabalhando com vários slots.
Onkel Toob
29

Apenas uma atualização para usuários do .NET core 2.0, você pode especificar a configuração do aplicativo após a chamada para 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);

   }
 }
umutesen
fonte
2
Como você alterna entre os ambientes que estão sendo usados? Há alterações que devem ser feitas em algum arquivo de configuração? Entendo que precisarei adicionar a URL que desejo usar quando o projeto for executado no Azure para appsettings.json e a URL que desejo executar quando executado localmente (por F5) para appsettings.Development.json . Isso é correto? Minha string que eu quero usar está no arquivo launchSettings.json e não estou certo de como alterá-la com base em onde o aplicativo é executado (ou se é para ser alterado).
DonkeyBanana
3
@DonkeyBanana O ambiente nada mais é do que uma configuração especificada nas propriedades do projeto. No VS 2017, clique com o botão direito no projeto> propriedades. Na depuração, você verá o ambiente atual da chave ASPNETCORE_ENVIRONMENT. O valor é o que será substituído ctx.HostingEnvironment.EnvironmentName}. Portanto, se você definir esse valor nas propriedades como 'Produção', o projeto irá procurar o config.Production.jsonarquivo na pasta raiz. Para obter mais informações, consulte este link
umutesen
Cria um Error CS0266 Cannot implicitly convert type 'Microsoft.AspNetCore.Hosting.IWebHost' to 'Microsoft.AspNetCore.Hosting.IWebHostBuilder'. An explicit conversion exists (are you missing a cast?) em WebHost.CreateDefaultBuiler (...
Hecatonchires
É importante notar que aqui ele afirma "AddJsonFile é automaticamente chamado duas vezes quando você inicializa um novo construtor de host com CreateDefaultBuilder". Em outras palavras, ele já está carregando appSettings.json e, com base na configuração do seu ambiente, está carregando appsettings. {Environment} .json
David Yates
@umutsen No último visual studio não há mais configurações de ambiente de execução
user1034912
13
  1. Crie vários arquivos como:appSettings.$(Configuration).json

    • appSettings.staging.json
    • appSettings.production.json
  2. Crie um evento de pré-construção no projeto que copia o respectivo arquivo para appSettings.json:

    copy appSettings.$(Configuration).json appSettings.json
    
  3. Use apenas appSettings.jsonno seu Config Builder:

    var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
    
    Configuration = builder.Build();
    
user3924036
fonte
Esta deve ser uma resposta aceita. Para casos complicados, SlowCheetah pode ser usado.
Anton Krouglov
8

Você pode adicionar o nome da configuração como ASPNETCORE_ENVIRONMENTna launchSettings.jsoncomo abaixo

  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:58446/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "environmentVariables": {
        ASPNETCORE_ENVIRONMENT": "$(Configuration)"
      }
    }
  }
Fleaca Dan
fonte
3

Esta é a versão que funciona para mim ao usar um aplicativo de console sem uma página da web:

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);
Nick Cordova
fonte
0

O arquivo .vscode / launch.json só é usado pelo Visual Studio, bem como o arquivo /Properties/launchSettings.json. Não use esses arquivos na produção.

O arquivo launchSettings.json:

  1. É usado apenas na máquina de desenvolvimento local.
  2. Não está implantado.
  3. contém configurações de perfil.

    • Os valores de ambiente definidos em launchSettings.json substituem os valores definidos no ambiente do sistema

Para usar um arquivo 'appSettings.QA.json' por exemplo. Você pode usar 'ASPNETCORE_ENVIRONMENT'. Siga os passos abaixo.

  1. Adicione uma nova variável de ambiente na máquina host e chame-a de 'ASPNETCORE_ENVIRONMENT'. Defina seu valor como 'QA'.
  2. Crie um arquivo 'appSettings.QA.json' em seu projeto. Adicione sua configuração aqui.
  3. Implante na máquina na etapa 1. Confirme se 'appSettings.QA.json' está implantado.
  4. Carregue seu site. Espere appSettings.QA.json para ser usado aqui.
Oks Xen
fonte