¿Configurar automáticamente appsettings.json para entornos de desarrollo y lanzamiento en asp.net core?

98

He definido algunos valores en mi appsettings.jsonpara cosas como cadenas de conexión de bases de datos, ubicaciones de webapi y similares, que son diferentes para entornos de desarrollo, puesta en escena y en vivo.

¿Hay alguna manera de tener varios appsettings.jsonarchivos (como appsettings.live.json, etc., etc.) y hacer que la aplicación asp.net simplemente 'sepa' cuál usar en función de la configuración de compilación que se está ejecutando?

tweetypi
fuente

Respuestas:

32

Puede utilizar la compilación 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
fuente
26
Debe establecer su variable de entorno en su compilación de MSBuild / TFS. La compilación condicional conduce a errores por algo que se maneja fácilmente en las compilaciones de CI. Es decir, .AddJsonFile ($ "appsettings. {Env.EnvironmentName} .json", opcional: verdadero)
Nick Turner
1
Vea mi respuesta ( stackoverflow.com/a/50331886/1319086 ) para la variable de entorno
Jonatan Dragon
9
Este tipo de enfoque obliga a que el código se recompile específicamente para cada entorno, lo que hace que sea imposible redistribuirlo / instalarlo en otro lugar.
tvdias
1
La pregunta era sobre "saber acerca de la configuración de compilación"
Dmitry
4
Esto no debe marcarse como la respuesta aceptada, aunque es una solución, no es la mejor práctica.
Charleh
96

He añadido capturas de pantalla de un entorno de trabajo porque me ha costado varias horas de I + D.

  1. Primero, agregue una clave a su launch.jsonarchivo.

    Vea la captura de pantalla a continuación, que he agregado Developmentcomo mi entorno.

    Declaración de la variable de entorno en launch.json

  2. Luego, en su proyecto, cree un nuevo appsettings.{environment}.jsonarchivo que incluya el nombre del entorno.

    En la siguiente captura de pantalla, busque dos archivos diferentes con los nombres:

    • appsettings.Development.Json
    • appSetting.json


    Vista del proyecto de archivos JSON de configuración de aplicaciones

  3. Y finalmente, configúrelo para su StartUpclase así:

    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. Y por último, puedes ejecutarlo desde la línea de comando así:

    dotnet run --environment "Development"
    

    donde "Development"esta el nombre de mi entorno.

Bharat
fuente
2
Probé esto y funciona muy bien. VS2017 incluso muestra las diferentes versiones como debajo del archivo base. voto a favor.
Roberto
1
¿Cómo se hace en el núcleo 2.2, ya que ihostingenvironment está obsoleto?
djack109
2
@ djack109 debería usar IWebHostEnvironmenten su lugar.
alessandrocb
53

Actualización para .NET Core 3.0+

  1. Puede usar CreateDefaultBuilderque automáticamente construirá y pasará un objeto de configuración a su clase de inicio:

    WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
    
    public class Startup
    {
        public Startup(IConfiguration configuration) // automatically injected
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        /* ... */
    }
    
  2. CreateDefaultBuilderincluye automáticamente el archivo apropiado , así que agregue un archivo de configuración de aplicaciones separado para cada entorno:appsettings.Environment.json

    appsettings.env.json

  3. Luego establezca la ASPNETCORE_ENVIRONMENT variable de entorno al ejecutar / depurar

Cómo configurar variables de entorno

Dependiendo de su IDE, hay un par de lugares donde los proyectos de dotnet tradicionalmente buscan variables de entorno:

  • Para Visual Studio, vaya a Proyecto> Propiedades> Depurar> Variables de entorno:

    Visual Studio: variables de entorno

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

    Código de Visual Studio> Entorno de lanzamiento

  • Usando Configuración de inicio , editar Properties/launchSettings.json> environmentVariables:

    Configuración de lanzamiento

    Que también se puede seleccionar de la barra de herramientas en Visual Studio

    Iniciar menú desplegable de configuración

  • Con la CLI de dotnet , utilice la sintaxis adecuada para configurar las variables de entorno según su sistema operativo

    Nota : Cuando se inicia una aplicación con dotnet run , launchSettings.jsonse lee si está disponible y la environmentVariablesconfiguración en launchSettings.json anula las variables de entorno.

¿Cómo Host.CreateDefaultBuilderfunciona?

Se agregó .NET Core 3.0 Host.CreateDefaultBuilderen las extensiones de plataforma que proporcionarán una inicialización predeterminada IConfigurationque proporciona la configuración predeterminada para la aplicación en el siguiente orden:

  1. appsettings.jsonutilizando el proveedor de configuración JSON .
  2. appsettings.Environment.jsonutilizando el proveedor de configuración JSON . Por ejemplo:
    • appsettings.Production.json o
    • appsettings.Development.json
  3. Secretos de la aplicación cuando la aplicación se ejecuta en el entorno de desarrollo.
  4. Variables de entorno que utilizan el proveedor de configuración de Variables de entorno .
  5. Argumentos de la línea de comandos que utilizan el proveedor de configuración de la línea de comandos .

Lectura adicional - MS Docs

KyleMit
fuente
Gracias, está bien, pero ¿cómo se hace con el proceso de la consola (o la plantilla / andamiaje del proceso del trabajador)?
hB0
44

En ASP.NET Core, debería utilizar variables de entorno en lugar de compilar la configuración para appsettings.json adecuada

  1. Haga clic derecho en su proyecto> Propiedades> Depurar> Variables de entorno

    Variables de entorno

  2. ASP.NET Core usará el archivo appsettings.json apropiado:

    ejemplo de archivos de configuración de aplicaciones en el explorador de soluciones

  3. Ahora puede usar esa variable de entorno de esta manera:

    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 : Si usa la respuesta de @ Dmitry , puede tener problemas, por ejemplo. al invalidar los valores de appsettings.json en Azure.

Dragón de Jonatán
fuente
35

Puede hacer uso de variables de entorno y la ConfigurationBuilderclase en su Startupconstructor de esta manera:

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

Luego, crea un appsettings.xxx.jsonarchivo para cada entorno que necesita, con "xxx" como nombre del entorno. Tenga en cuenta que puede poner todos los valores de configuración global en su "normal"appsettings.json archivo y solo poner las cosas específicas del entorno en estos nuevos archivos.

Ahora solo necesita una variable de entorno llamada ASPNETCORE_ENVIRONMENTcon algún valor de entorno específico ("en vivo", "puesta en escena", "producción", lo que sea). Puede especificar esta variable en la configuración de su proyecto para su entorno de desarrollo y, por supuesto, también debe establecerla en sus entornos de ensayo y producción. La forma en que lo haga depende del tipo de entorno que sea.

ACTUALIZACIÓN: Me acabo de dar cuenta de que desea elegir el appsettings.xxx.jsonbasado en su configuración de compilación actual . Esto no se puede lograr con mi solución propuesta y no sé si hay una manera de hacerlo. La forma de "variable de entorno", sin embargo, funciona y bien podría ser una buena alternativa a su enfoque.

Onkel Toob
fuente
Miré el uso de variables de entorno, en las propiedades del proyecto-> sección de depuración, sin embargo, no hay una forma obvia de cómo esto cambiará según la configuración del proyecto. ¿Es ese otro archivo que puedo agregar a mi proyecto para manejarlo?
tweetypi
Establecer la variable dentro de las propiedades del proyecto solo funcionará para usarla en su entorno de desarrollo (probablemente Visual Studio). Deberá configurarlo en otro lugar para sus aplicaciones implementadas según el entorno específico (IIS, Azure). No recomendaría establecer la variable en algún archivo de configuración porque este archivo también podría implementarse y luego anular los valores del servidor.
Onkel Toob
Lo configura en configuraciones de compilación. Si no hay un archivo de configuración de compilación, lo están haciendo manualmente, por lo que deberían configurarlo en el perfil de implementación (arcaico)
Nick Turner
Tengo múltiples entornos como prueba, puesta en escena y producción en Azure. ¿Dónde cambio la variable ASPNETCORE_ENVIRONMENT si quiero publicar la compilación de lanzamiento de la aplicación web de VS a Azure?
helado
No cambiamos las variables durante la implementación, sino que están integradas en el entorno específico. En Azure, puede establecer estos valores directamente dentro de la configuración de su servicio de aplicaciones en "Configuración de la aplicación". No olvide marcarlos como "Configuración de ranura de implementación" en caso de que esté trabajando con varias ranuras.
Onkel Toob
29

Solo una actualización para los usuarios de .NET core 2.0, puede especificar la configuración de la aplicación después de la llamada a 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
fuente
1
¿Cómo cambia entre los entornos que se utilizan? ¿Se supone que se deben realizar cambios en algún archivo de configuración? Entiendo que tendré que agregar la URL que quiero usar cuando el proyecto se ejecute en Azure a appsettings.json y la URL que quiero ejecutar cuando se ejecute localmente (por F5) a appsettings.Development.json . ¿Es eso correcto? Mi cadena que quiero usar está en el archivo launchSettings.json y no tengo claro cómo modificarla en función de dónde se ejecuta la aplicación (o si se supone que debe modificarse).
DonkeyBanana
3
@DonkeyBanana El entorno no es más que una configuración especificada en las propiedades del proyecto. En VS 2017, haga clic derecho en el proyecto> propiedades. En depuración, verá el entorno actual de key ASPNETCORE_ENVIRONMENT. El valor es lo que será reemplazado ctx.HostingEnvironment.EnvironmentName}. Entonces, si establece ese valor en las propiedades en 'Producción', el proyecto buscará el config.Production.jsonarchivo en la carpeta raíz. Para obtener más información, consulte este enlace
umutesen
Crea un Error CS0266 Cannot implicitly convert type 'Microsoft.AspNetCore.Hosting.IWebHost' to 'Microsoft.AspNetCore.Hosting.IWebHostBuilder'. An explicit conversion exists (are you missing a cast?) WebHost.CreateDefaultBuiler (...
Hecatonchires
Vale la pena señalar que aquí dice "AddJsonFile se llama automáticamente dos veces cuando inicializa un nuevo generador de host con CreateDefaultBuilder". En otras palabras, ya está cargando appSettings.json y luego, según la configuración de su entorno, está cargando appsettings. {Environment} .json
David Yates
13
  1. Crea varios archivos como:appSettings.$(Configuration).json

    • appSettings.staging.json
    • appSettings.production.json
  2. Cree un evento previo a la construcción en el proyecto que copie el archivo respectivo en appSettings.json:

    copy appSettings.$(Configuration).json appSettings.json
    
  3. Usar unicamente appSettings.json en su Config Builder:

    var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
    
    Configuration = builder.Build();
    
user3924036
fuente
Esta debería ser una respuesta aceptada. Para casos complicados, se puede utilizar SlowCheetah .
Anton Krouglov
8

Se puede añadir el nombre de la configuración como la ASPNETCORE_ENVIRONMENTde la launchSettings.jsonde la siguiente

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

Esta es la versión que me funciona cuando uso una aplicación de consola sin una página 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
fuente
0

El archivo .vscode / launch.json solo lo usa Visual Studio, así como el archivo /Properties/launchSettings.json. No utilice estos archivos en producción.

El archivo launchSettings.json:

  1. Solo se usa en la máquina de desarrollo local.
  2. No está desplegado.
  3. contiene la configuración del perfil.

    • Los valores del entorno establecidos en launchSettings.json anulan los valores establecidos en el entorno del sistema

Para usar un archivo 'appSettings.QA.json', por ejemplo. Puede utilizar 'ASPNETCORE_ENVIRONMENT'. Siga los pasos a continuación.

  1. Agregue una nueva variable de entorno en la máquina host y llámela 'ASPNETCORE_ENVIRONMENT'. Establezca su valor en 'QA'.
  2. Cree un archivo 'appSettings.QA.json' en su proyecto. Agregue su configuración aquí.
  3. Implemente en la máquina en el paso 1. Confirme que 'appSettings.QA.json' esté implementado.
  4. Cargue su sitio web. Espere que appSettings.QA.json se use aquí.
Ok Xen
fuente