Usar varios entornos en ASP.NET Core

Por Rick Anderson y Kirk Larkin

ASP.NET Core configura el comportamiento de las aplicaciones en función del entorno en tiempo de ejecución mediante una variable de entorno.

Vea o descargue el código de ejemplo (cómo descargarlo)

Entornos

Para determinar el entorno de ejecución, ASP.NET Core lee de las siguientes variables de entorno:

  1. DOTNET_ENVIRONMENT
  2. ASPNETCORE_ENVIRONMENT cuando se llama a ConfigureWebHostDefaults. Las plantillas de aplicación web de ASP.NET Core predeterminadas llaman a ConfigureWebHostDefaults. El valor ASPNETCORE_ENVIRONMENT invalida DOTNET_ENVIRONMENT.

IHostEnvironment.EnvironmentName se puede establecer en cualquier valor, pero el marco proporciona los siguientes valores:

El código siguiente:

  • Llama a UseDeveloperExceptionPage cuando ASPNETCORE_ENVIRONMENT está establecido en Development.
  • Llama a UseExceptionHandler cuando el valor de ASPNETCORE_ENVIRONMENT se establece en Staging, Production o Staging_2.
  • Inserta IWebHostEnvironment en Startup.Configure. Este enfoque es útil cuando la aplicación solo requiere el ajuste de Startup.Configure para algunos entornos con diferencias de código mínimas en cada uno.
  • Es similar al código generado por las plantillas de ASP.NET Core.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

El asistente de etiquetas de entorno utiliza el valor de IHostEnvironment.EnvironmentName para incluir o excluir el marcado en el elemento:

<environment include="Development">
    <div>The effective tag is: &lt;environment include="Development"&gt;</div>
</environment>
<environment exclude="Development">
    <div>The effective tag is: &lt;environment exclude="Development"&gt;</div>
</environment>
<environment include="Staging,Development,Staging_2">
    <div>
        The effective tag is:
        &lt;environment include="Staging,Development,Staging_2"&gt;
    </div>
</environment>

La página Acerca de del código de ejemplo incluye el marcado anterior y muestra el valor de IWebHostEnvironment.EnvironmentName.

En Windows y macOS, los valores y las variables de entorno no distinguen mayúsculas de minúsculas. Los valores y las variables de entorno de Linux distinguen mayúsculas de minúsculas de forma predeterminada.

Creación de EnvironmentsSample

El código de ejemplo utilizado en este documento se basa en un proyecto de páginas Razor denominado EnvironmentsSample.

El código siguiente crea y ejecuta una aplicación web denominada EnvironmentsSample:

dotnet new webapp -o EnvironmentsSample
cd EnvironmentsSample
dotnet run --verbosity normal

Cuando se ejecuta la aplicación, muestra algunas de las salidas siguientes:

Using launch settings from c:\tmp\EnvironmentsSample\Properties\launchSettings.json
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: c:\tmp\EnvironmentsSample

Desarrollo y launchSettings.json

El entorno de desarrollo puede habilitar características que no deben exponerse en producción. Por ejemplo, las plantillas de ASP.NET Core habilitan la página de excepciones para el desarrollador en el entorno de desarrollo.

El entorno para el desarrollo del equipo local se puede establecer en el archivo Properties\launchSettings.json del proyecto. Los valores de entorno establecidos en launchSettings.json invalidan los valores establecidos en el entorno del sistema.

El archivo launchSettings.json:

  • Solo se usa en el equipo de desarrollo local.
  • No se implementa.
  • Contiene la configuración del perfil.

El siguiente JSON muestra el archivo launchSettings.json para un proyecto web de ASP.NET Core denominado EnvironmentsSample creado con Visual Studio o dotnet new:

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:64645",
      "sslPort": 44366
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "EnvironmentsSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

El marcado anterior contiene dos perfiles:

  • IIS Express: El perfil predeterminado que se usa cuando se inicia la aplicación en Visual Studio. La clave "commandName" tiene el valor "IISExpress", por lo tanto, IISExpress es el servidor web. Puede establecer el perfil de inicio en el proyecto o en cualquier otro perfil incluido. Por ejemplo, en la imagen siguiente, al seleccionar el nombre del proyecto se inicia el servidor web de Kestrel.

    Inicio de IIS Express en el menú

  • EnvironmentsSample: El nombre del perfil es el nombre del proyecto. Este perfil se utiliza de forma predeterminada al iniciar la aplicación con dotnet run. La clave "commandName" tiene el valor "Project", por lo tanto, se inicia el servidor web de Kestrel.

El valor de commandName puede especificar el servidor web que se va a iniciar. commandName puede ser uno de los siguientes:

  • IISExpress: Inicia IIS Express.
  • IIS: No se ha iniciado ningún servidor web. Se espera que IIS esté disponible.
  • Project: Inicia Kestrel.

La pestaña Depurar de las propiedades de proyecto de Visual Studio proporciona una GUI para editar el archivo launchSettings.json. Los cambios realizados en los perfiles de proyecto podrían no surtir efecto hasta que se reinicie el servidor web. Es necesario reiniciar Kestrel para que pueda detectar los cambios realizados en su entorno.

Variables de entorno de configuración de las propiedades del proyecto

El archivo launchSettings.json siguiente contiene varios perfiles:

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:64645",
      "sslPort": 44366
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IISX-Production": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      }
    },
    "IISX-Staging": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging",
        "ASPNETCORE_DETAILEDERRORS": "1",
        "ASPNETCORE_SHUTDOWNTIMEOUTSECONDS": "3"
      }
    },
    "EnvironmentsSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "KestrelStaging": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    }
  }
}

Los perfiles se pueden seleccionar de la forma siguiente:

  • Desde la interfaz de usuario de Visual Studio.

  • Mediante el comando dotnet run en un shell de comandos con la opción --launch-profile establecida en el nombre del perfil. Este enfoque solo admite perfiles de Kestrel.

    dotnet run --launch-profile "SampleApp"
    

Advertencia

En launchSettings.json no se deben almacenar secretos. Se puede usar la herramienta Administrador de secretos a fin de almacenar secretos para el desarrollo local.

Cuando se usa Visual Studio Code, las variables de entorno se pueden establecer en el archivo .vscode/launch.json. En el ejemplo siguiente se establecen varias variables de entorno de valores de configuración de host:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (web)",
            "type": "coreclr",
            // Configuration ommitted for brevity.
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development",
                "ASPNETCORE_URLS": "https://localhost:5001",
                "ASPNETCORE_DETAILEDERRORS": "1",
                "ASPNETCORE_SHUTDOWNTIMEOUTSECONDS": "3"
            },
            // Configuration ommitted for brevity.

El archivo .vscode/launch.json solo lo usa Visual Studio Code.

Producción

El entorno de producción debe configurarse para maximizar la seguridad, el rendimiento y la solidez de la aplicación. Las opciones de configuración comunes que difieren de las del entorno de desarrollo son:

  • Almacenamiento en caché.
  • Los recursos del cliente se agrupan, se reducen y se atienden potencialmente desde una CDN.
  • Las páginas de error de diagnóstico están deshabilitadas.
  • Las páginas de error descriptivas están habilitadas.
  • El registro y la supervisión de la producción están habilitados. Por ejemplo, mediante Application Insights.

Establecimiento del entorno

A menudo resulta útil establecer un entorno específico para realizar las pruebas con una variable de entorno o una configuración de plataforma. Si el entorno no está establecido, el valor predeterminado es Production, lo que deshabilita la mayoría de las características de depuración. El método para establecer el entorno depende del sistema operativo.

Cuando se compila el host, la última configuración de entorno leída por la aplicación determina el entorno de la aplicación. El entorno de la aplicación no se puede cambiar mientras se ejecuta la aplicación.

La página Acerca de del código de ejemplo muestra el valor de IWebHostEnvironment.EnvironmentName.

Azure App Service

Para establecer el entorno en Azure App Service, realice los pasos siguientes:

  1. Seleccione la aplicación desde la hoja App Services.
  2. En el grupo Configuración, seleccione la hoja Configuración.
  3. En la pestaña Configuración de aplicaciones, seleccione Nueva configuración de aplicación.
  4. En la ventana Agregar o editar la configuración de la aplicación, escriba ASPNETCORE_ENVIRONMENT para el Nombre. En Valor, proporcione el entorno (por ejemplo, Staging).
  5. Active la casilla Configuración de ranura de implementación si quiere que la configuración del entorno permanezca con la ranura actual cuando se intercambien las ranuras de implementación. Para más información, consulte Configuración de entornos de ensayo en Azure App Service en la documentación de Azure.
  6. Seleccione Aceptar para cerrar la ventana Agregar o editar la configuración de la aplicación.
  7. Seleccione Guardar en la parte superior de la hoja Configuración.

Azure App Service reinicia automáticamente la aplicación después de que se agregue, cambie o elimine una configuración de aplicación en Azure Portal.

Windows

Los valores de entorno de launchSettings.json invalidan los valores establecidos en el entorno del sistema.

Para establecer ASPNETCORE_ENVIRONMENT en la sesión actual, cuando la aplicación se ha iniciado con dotnet run, use los comandos siguientes:

Símbolo del sistema

set ASPNETCORE_ENVIRONMENT=Staging
dotnet run --no-launch-profile

PowerShell

$Env:ASPNETCORE_ENVIRONMENT = "Staging"
dotnet run --no-launch-profile

El comando anterior se establece ASPNETCORE_ENVIRONMENT solo para los procesos iniciados desde esa ventana de comandos.

Para establecer el valor globalmente en Windows, use cualquiera de los métodos siguientes:

  • Abra el Panel de control > Sistema > Configuración avanzada del sistema y agregue o edite el valor ASPNETCORE_ENVIRONMENT:

    Propiedades avanzadas del sistema

    Variable de entorno de ASP.NET Core

  • Abra un símbolo del sistema con permisos de administrador y use el comando setx o abra un símbolo del sistema administrativo de PowerShell y use [Environment]::SetEnvironmentVariable:

    Símbolo del sistema

    setx ASPNETCORE_ENVIRONMENT Staging /M
    

    El modificador /M indica que hay que establecer la variable de entorno en el nivel de sistema. Si no se usa el modificador /M, la variable de entorno se establece para la cuenta de usuario.

    PowerShell

    [Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Staging", "Machine")
    

    El valor de opción Machine indica que hay que establecer la variable de entorno en el nivel de sistema. Si el valor de opción se cambia a User, la variable de entorno se establece para la cuenta de usuario.

Cuando la variable de entorno ASPNETCORE_ENVIRONMENT se establece de forma global, se aplica a dotnet run en cualquier ventana de comandos abierta después del establecimiento del valor. Los valores de entorno de launchSettings.json invalidan los valores establecidos en el entorno del sistema.

web.config

Para establecer la variable de entorno ASPNETCORE_ENVIRONMENT con web.config, vea la sección Establecimiento de variables de entorno de Módulo ASP.NET Core.

Archivo del proyecto o perfil de publicación

Para las implementaciones de IIS de Windows: Incluya la propiedad <EnvironmentName> del perfil de publicación (.pubxml) o un archivo de proyecto. Este método establece el entorno en web.config cuando se publica el proyecto:

<PropertyGroup>
  <EnvironmentName>Development</EnvironmentName>
</PropertyGroup>

Por grupo de aplicaciones de IIS

Para establecer la variable de entorno ASPNETCORE_ENVIRONMENT para una aplicación que se ejecuta en un grupo de aplicaciones aislado (se admite en IIS 10.0 o posterior), vea la sección AppCmd.exe del tema Environment Variables <environmentVariables> (Variables de entorno). Cuando la variable de entorno ASPNETCORE_ENVIRONMENT se establece para un grupo de aplicaciones, su valor reemplaza a un valor en el nivel de sistema.

Cuando hospede una aplicación en IIS y agregue o cambie la variable de entorno ASPNETCORE_ENVIRONMENT, use cualquiera de los siguientes métodos para que las aplicaciones tomen el nuevo valor:

  • Ejecute net stop was /y seguido de net start w3svc en un símbolo del sistema.
  • Reinicie el servidor.

macOS

Para establecer el entorno actual para macOS, puede hacerlo en línea al ejecutar la aplicación:

ASPNETCORE_ENVIRONMENT=Staging dotnet run

De forma alternativa, defina el entorno con export antes de ejecutar la aplicación:

export ASPNETCORE_ENVIRONMENT=Staging

Las variables de entorno de nivel de equipo se establecen en el archivo .bashrc o .bash_profile. Edite el archivo con cualquier editor de texto. Agregue la siguiente instrucción:

export ASPNETCORE_ENVIRONMENT=Staging

Linux

Para distribuciones de Linux, use el comando export en un símbolo del sistema para la configuración de variables basada en sesión y el archivo bash_profile para la configuración del entorno en el nivel de equipo.

Establecimiento del entorno en el código

Llame a UseEnvironment al compilar el host. Vea Host genérico de .NET en ASP.NET Core.

Configuración de entorno

Para cargar la configuración por entorno, consulte Configuración en ASP.NET Core.

Métodos y clase Startup basados en entorno

Inserción de IWebHostEnvironment en la clase Startup

Inserte IWebHostEnvironment en el constructor de Startup. Este enfoque es útil cuando la aplicación solo requiere la configuración de Startup para algunos entornos con diferencias de código mínimas en cada uno.

En el ejemplo siguiente:

  • El entorno se mantiene en el campo _env.
  • _env se usa en ConfigureServices y Configure para aplicar la configuración de inicio en función del entorno de la aplicación.
public class Startup
{
    public Startup(IConfiguration configuration, IWebHostEnvironment env)
    {
        Configuration = configuration;
        _env = env;
    }

    public IConfiguration Configuration { get; }
    private readonly IWebHostEnvironment _env;

    public void ConfigureServices(IServiceCollection services)
    {
        if (_env.IsDevelopment())
        {
            Console.WriteLine(_env.EnvironmentName);
        }
        else if (_env.IsStaging())
        {
            Console.WriteLine(_env.EnvironmentName);
        }
        else
        {
            Console.WriteLine("Not dev or staging");
        }

        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {
        if (_env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Convenciones de la clase Startup

Cuando se inicia una aplicación ASP.NET Core, la clase Startup arranca la aplicación. La aplicación puede definir varias clases de Startup para diferentes entornos. La clase Startup correspondiente se selecciona en tiempo de ejecución. La clase cuyo sufijo de nombre coincide con el entorno actual se establece como prioritaria. Si no se encuentra una clase Startup{EnvironmentName} coincidente, se usa la clase Startup. Este enfoque es útil cuando la aplicación requiere configurar el inicio para algunos entornos con muchas diferencias de código en cada uno. Las aplicaciones típicas no necesitarán este enfoque.

Para implementar clases Startup basadas en entornos, cree una clase Startup{EnvironmentName} y una clase Startup de reserva:

public class StartupDevelopment
{
    public StartupDevelopment(IConfiguration configuration)
    {
        Configuration = configuration;
        Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseDeveloperExceptionPage();

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

public class StartupProduction
{
    public StartupProduction(IConfiguration configuration)
    {
        Configuration = configuration;
        Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {

        app.UseExceptionHandler("/Error");
        app.UseHsts();

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Use la sobrecarga UseStartup(IWebHostBuilder, String) que acepta un nombre de ensamblado:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var assemblyName = typeof(Startup).GetTypeInfo().Assembly.FullName;

        return   Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup(assemblyName);
            });
    }
}

Convenciones del método Startup

Configure y ConfigureServices son compatibles con versiones específicas del entorno con el formato Configure<EnvironmentName> y Configure<EnvironmentName>Services. Este enfoque es útil cuando la aplicación requiere configurar el inicio para algunos entornos con muchas diferencias de código en cada uno:

public class Startup
{
    private void StartupConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void ConfigureDevelopmentServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void ConfigureStagingServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void ConfigureProductionServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void ConfigureServices(IServiceCollection services)
    {
        MyTrace.TraceMessage();
        StartupConfigureServices(services);
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        MyTrace.TraceMessage();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }

    public void ConfigureStaging(IApplicationBuilder app, IWebHostEnvironment env)
    {
        MyTrace.TraceMessage();

        app.UseExceptionHandler("/Error");
        app.UseHsts();

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

public static class MyTrace
{
    public static void TraceMessage([CallerMemberName] string memberName = "")
    {
        Console.WriteLine($"Method: {memberName}");
    }
}

Recursos adicionales

Por Rick Anderson

ASP.NET Core configura el comportamiento de las aplicaciones en función del entorno en tiempo de ejecución mediante una variable de entorno.

Vea o descargue el código de ejemplo (cómo descargarlo)

Entornos

ASP.NET Core lee la variable de entorno ASPNETCORE_ENVIRONMENT al inicio de la aplicación y almacena el valor en IHostingEnvironment.EnvironmentName. ASPNETCORE_ENVIRONMENT se puede establecer en cualquier valor, pero el marco proporciona tres valores:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseMvc();
}

El código anterior:

  • Llama a UseDeveloperExceptionPage cuando ASPNETCORE_ENVIRONMENT está establecido en Development.

  • Llama a UseExceptionHandler cuando el valor de ASPNETCORE_ENVIRONMENT está establecido en uno de los siguientes:

    • Staging
    • Production
    • Staging_2

El asistente de etiquetas de entorno usa el valor de IHostingEnvironment.EnvironmentName para incluir o excluir el marcado en el elemento:

<environment include="Development">
    <div>The effective tag is: &lt;environment include="Development"&gt;</div>
</environment>
<environment exclude="Development">
    <div>The effective tag is: &lt;environment exclude="Development"&gt;</div>
</environment>
<environment include="Staging,Development,Staging_2">
    <div>
        The effective tag is:
        &lt;environment include="Staging,Development,Staging_2"&gt;
    </div>
</environment>

En Windows y macOS, los valores y las variables de entorno no distinguen mayúsculas de minúsculas. Los valores y las variables de entorno de Linux distinguen mayúsculas de minúsculas de forma predeterminada.

Desarrollo

El entorno de desarrollo puede habilitar características que no deben exponerse en producción. Por ejemplo, las plantillas de ASP.NET Core habilitan la página de excepciones para el desarrollador en el entorno de desarrollo.

El entorno para el desarrollo del equipo local se puede establecer en el archivo Properties\launchSettings.json del proyecto. Los valores de entorno establecidos en launchSettings.json invalidan los valores establecidos en el entorno del sistema.

En el siguiente fragmento de JSON se muestran tres perfiles de un archivo launchSettings.json:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:54339/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_My_Environment": "1",
        "ASPNETCORE_DETAILEDERRORS": "1",
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    },
    "EnvironmentsSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      },
      "applicationUrl": "http://localhost:54340/"
    },
    "Kestrel Staging": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_My_Environment": "1",
        "ASPNETCORE_DETAILEDERRORS": "1",
        "ASPNETCORE_ENVIRONMENT": "Staging"
      },
      "applicationUrl": "http://localhost:51997/"
    }
  }
}

Nota

La propiedad applicationUrl en launchSettings.json puede especificar una lista de direcciones URL del servidor. Use un punto y coma entre las direcciones URL de la lista:

"EnvironmentsSample": {
   "commandName": "Project",
   "launchBrowser": true,
   "applicationUrl": "https://localhost:5001;http://localhost:5000",
   "environmentVariables": {
     "ASPNETCORE_ENVIRONMENT": "Development"
   }
}

Cuando la aplicación se inicia con dotnet run, se usa el primer perfil con "commandName": "Project". El valor de commandName especifica el servidor web que se va a iniciar. commandName puede ser uno de los siguientes:

  • IISExpress
  • IIS
  • Project (que inicia Kestrel)

Cuando una aplicación se inicia con dotnet run:

  • Se lee launchSettings.json, si está disponible. La configuración de environmentVariables de launchSettings.json reemplaza las variables de entorno.
  • Se muestra el entorno de hospedaje.

En la siguiente salida se muestra una aplicación que se ha iniciado con dotnet run:

PS C:\Websites\EnvironmentsSample> dotnet run
Using launch settings from C:\Websites\EnvironmentsSample\Properties\launchSettings.json...
Hosting environment: Staging
Content root path: C:\Websites\EnvironmentsSample
Now listening on: http://localhost:54340
Application started. Press Ctrl+C to shut down.

La pestaña Depurar de las propiedades de proyecto de Visual Studio proporciona una GUI para editar el archivo launchSettings.json:

Variables de entorno de configuración de las propiedades del proyecto

Los cambios realizados en los perfiles de proyecto podrían no surtir efecto hasta que se reinicie el servidor web. Es necesario reiniciar Kestrel para que pueda detectar los cambios realizados en su entorno.

Advertencia

En launchSettings.json no se deben almacenar secretos. Se puede usar la herramienta Administrador de secretos a fin de almacenar secretos para el desarrollo local.

Cuando se usa Visual Studio Code, las variables de entorno se pueden establecer en el archivo .vscode/launch.json. En el siguiente ejemplo se establece el entorno en Development:

{
   "version": "0.2.0",
   "configurations": [
        {
            "name": ".NET Core Launch (web)",

            ... additional VS Code configuration settings ...

            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            }
        }
    ]
}

Un archivo .vscode/launch.json del proyecto no se lee al iniciar la aplicación con dotnet run en la misma manera que Properties/launchSettings.json. Cuando se inicia una aplicación en desarrollo que no tiene un archivo launchSettings.json, establezca el valor del entorno con una variable de entorno o con un argumento de línea de comandos para el comando dotnet run.

Producción

El entorno de producción debe configurarse para maximizar la seguridad, el rendimiento y la solidez de la aplicación. Las opciones de configuración comunes que difieren de las del entorno de desarrollo son:

  • Almacenamiento en caché.
  • Los recursos del cliente se agrupan, se reducen y se atienden potencialmente desde una CDN.
  • Las páginas de error de diagnóstico están deshabilitadas.
  • Las páginas de error descriptivas están habilitadas.
  • El registro y la supervisión de la producción están habilitados. Por ejemplo, Application Insights.

Establecimiento del entorno

A menudo resulta útil establecer un entorno específico para realizar las pruebas con una variable de entorno o una configuración de plataforma. Si el entorno no está establecido, el valor predeterminado es Production, lo que deshabilita la mayoría de las características de depuración. El método para establecer el entorno depende del sistema operativo.

Cuando se compila el host, la última configuración de entorno leída por la aplicación determina el entorno de la aplicación. El entorno de la aplicación no se puede cambiar mientras se ejecuta la aplicación.

Configuración de plataforma o variable de entorno

Azure App Service

Para establecer el entorno en Azure App Service, realice los pasos siguientes:

  1. Seleccione la aplicación desde la hoja App Services.
  2. En el grupo Configuración, seleccione la hoja Configuración.
  3. En la pestaña Configuración de aplicaciones, seleccione Nueva configuración de aplicación.
  4. En la ventana Agregar o editar la configuración de la aplicación, escriba ASPNETCORE_ENVIRONMENT para el Nombre. En Valor, proporcione el entorno (por ejemplo, Staging).
  5. Active la casilla Configuración de ranura de implementación si quiere que la configuración del entorno permanezca con la ranura actual cuando se intercambien las ranuras de implementación. Para más información, consulte Configuración de entornos de ensayo en Azure App Service en la documentación de Azure.
  6. Seleccione Aceptar para cerrar la ventana Agregar o editar la configuración de la aplicación.
  7. Seleccione Guardar en la parte superior de la hoja Configuración.

Azure App Service reinicia automáticamente la aplicación después de que se agregue, cambie o elimine una configuración de aplicación (variable de entorno) en Azure Portal.

Windows

Para establecer ASPNETCORE_ENVIRONMENT en la sesión actual, cuando la aplicación se ha iniciado con dotnet run, use los comandos siguientes:

Símbolo del sistema

set ASPNETCORE_ENVIRONMENT=Development

PowerShell

$Env:ASPNETCORE_ENVIRONMENT = "Development"

Estos comandos solo tienen efecto en la ventana actual. Cuando se cierre la ventana, la configuración de ASPNETCORE_ENVIRONMENT volverá a la configuración predeterminada o al valor del equipo.

Para establecer el valor globalmente en Windows, use cualquiera de los métodos siguientes:

  • Abra el Panel de control > Sistema > Configuración avanzada del sistema y agregue o edite el valor ASPNETCORE_ENVIRONMENT:

    Propiedades avanzadas del sistema

    Variable de entorno de ASP.NET Core

  • Abra un símbolo del sistema con permisos de administrador y use el comando setx o abra un símbolo del sistema administrativo de PowerShell y use [Environment]::SetEnvironmentVariable:

    Símbolo del sistema

    setx ASPNETCORE_ENVIRONMENT Development /M
    

    El modificador /M indica que hay que establecer la variable de entorno en el nivel de sistema. Si no se usa el modificador /M, la variable de entorno se establece para la cuenta de usuario.

    PowerShell

    [Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "Machine")
    

    El valor de opción Machine indica que hay que establecer la variable de entorno en el nivel de sistema. Si el valor de opción se cambia a User, la variable de entorno se establece para la cuenta de usuario.

Cuando la variable de entorno ASPNETCORE_ENVIRONMENT se establece de forma global, se aplica a dotnet run en cualquier ventana de comandos abierta después del establecimiento del valor.

web.config

Para establecer la variable de entorno ASPNETCORE_ENVIRONMENT con web.config, vea la sección Establecimiento de variables de entorno de Módulo ASP.NET Core.

Archivo del proyecto o perfil de publicación

Para las implementaciones de IIS de Windows: Incluya la propiedad <EnvironmentName> del perfil de publicación (.pubxml) o un archivo de proyecto. Este método establece el entorno en web.config cuando se publica el proyecto:

<PropertyGroup>
  <EnvironmentName>Development</EnvironmentName>
</PropertyGroup>

Por grupo de aplicaciones de IIS

Para establecer la variable de entorno ASPNETCORE_ENVIRONMENT para una aplicación que se ejecuta en un grupo de aplicaciones aislado (se admite en IIS 10.0 o posterior), vea la sección AppCmd.exe del tema Environment Variables <environmentVariables> (Variables de entorno). Cuando la variable de entorno ASPNETCORE_ENVIRONMENT se establece para un grupo de aplicaciones, su valor reemplaza a un valor en el nivel de sistema.

Importante

Cuando hospede una aplicación en IIS y agregue o cambie la variable de entorno ASPNETCORE_ENVIRONMENT, use cualquiera de los siguientes métodos para que las aplicaciones tomen el nuevo valor:

  • Ejecute net stop was /y seguido de net start w3svc en un símbolo del sistema.
  • Reinicie el servidor.

macOS

Para establecer el entorno actual para macOS, puede hacerlo en línea al ejecutar la aplicación:

ASPNETCORE_ENVIRONMENT=Development dotnet run

De forma alternativa, defina el entorno con export antes de ejecutar la aplicación:

export ASPNETCORE_ENVIRONMENT=Development

Las variables de entorno de nivel de equipo se establecen en el archivo .bashrc o .bash_profile. Edite el archivo con cualquier editor de texto. Agregue la siguiente instrucción:

export ASPNETCORE_ENVIRONMENT=Development

Linux

Para distribuciones de Linux, use el comando export en un símbolo del sistema para la configuración de variables basada en sesión y el archivo bash_profile para la configuración del entorno en el nivel de equipo.

Establecimiento del entorno en el código

Llame a UseEnvironment al compilar el host. Vea Host web de ASP.NET Core.

Configuración de entorno

Para cargar la configuración por entorno, se recomienda lo siguiente:

Métodos y clase Startup basados en entorno

Inserción de IHostingEnvironment en Startup.Configure

Inserte IHostingEnvironment en Startup.Configure. Este enfoque es útil cuando la aplicación solo requiere la configuración de Startup.Configure para algunos entornos con diferencias de código mínimas en cada uno.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Development environment code
    }
    else
    {
        // Code for all other environments
    }
}

Inserción de IHostingEnvironment en la clase Startup

Inserte IHostingEnvironment en el constructor Startup y asigne el servicio a un campo para su uso en la clase Startup. Este enfoque es útil cuando la aplicación solo requiere configurar el inicio para algunos entornos con diferencias de código mínimas en cada uno.

En el ejemplo siguiente:

  • El entorno se mantiene en el campo _env.
  • _env se usa en ConfigureServices y Configure para aplicar la configuración de inicio en función del entorno de la aplicación.
public class Startup
{
    private readonly IHostingEnvironment _env;

    public Startup(IHostingEnvironment env)
    {
        _env = env;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        if (_env.IsDevelopment())
        {
            // Development environment code
        }
        else if (_env.IsStaging())
        {
            // Staging environment code
        }
        else
        {
            // Code for all other environments
        }
    }

    public void Configure(IApplicationBuilder app)
    {
        if (_env.IsDevelopment())
        {
            // Development environment code
        }
        else
        {
            // Code for all other environments
        }
    }
}

Convenciones de la clase Startup

Cuando se inicia una aplicación ASP.NET Core, la clase Startup arranca la aplicación. La aplicación puede definir clases Startup independientes para distintos entornos (por ejemplo, StartupDevelopment). La clase Startup correspondiente se selecciona en tiempo de ejecución. La clase cuyo sufijo de nombre coincide con el entorno actual se establece como prioritaria. Si no se encuentra una clase Startup{EnvironmentName} coincidente, se usa la clase Startup. Este enfoque es útil cuando la aplicación requiere configurar el inicio para algunos entornos con muchas diferencias de código en cada uno.

Para implementar clases Startup basadas en entornos, cree una clase Startup{EnvironmentName} para cada entorno en uso y una clase Startup de reserva:

// Startup class to use in the Development environment
public class StartupDevelopment
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

// Startup class to use in the Production environment
public class StartupProduction
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

// Fallback Startup class
// Selected if the environment doesn't match a Startup{EnvironmentName} class
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    }
}

Use la sobrecarga UseStartup(IWebHostBuilder, String) que acepta un nombre de ensamblado:

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    var assemblyName = typeof(Startup).GetTypeInfo().Assembly.FullName;

    return WebHost.CreateDefaultBuilder(args)
        .UseStartup(assemblyName);
}

Convenciones del método Startup

Configure y ConfigureServices son compatibles con versiones específicas del entorno con el formato Configure<EnvironmentName> y Configure<EnvironmentName>Services. Este enfoque es útil cuando la aplicación requiere configurar el inicio para algunos entornos con muchas diferencias de código en cada uno.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        StartupConfigureServices(services);
    }

    public void ConfigureStagingServices(IServiceCollection services)
    {
        StartupConfigureServices(services);
    }

    private void StartupConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
        {
            app.UseExceptionHandler("/Error");
        }

        app.UseStaticFiles();
        app.UseMvc();
    }

    public void ConfigureStaging(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (!env.IsStaging())
        {
            throw new Exception("Not staging.");
        }

        app.UseExceptionHandler("/Error");
        app.UseStaticFiles();
        app.UseMvc();
    }
}

Recursos adicionales