Configuración de una aplicación de ASP.NET para Azure App Service

Nota

Para ASP.NET en .NET Framework, consulte Configurar una aplicación de ASP.NET para Azure App Service. Si la aplicación ASP.NET Core se ejecuta en un contenedor personalizado de Windows o Linux, consulte Configuración de un contenedor personalizado para Azure App Service.

Las aplicaciones de ASP.NET Core deben implementarse en Azure App Service como binarios compilados. La herramienta de publicación de Visual Studio compila la solución y, a continuación, implementa los binarios compilados directamente, mientras que el motor de implementación de App Service implementa el repositorio de código en primer lugar y, a continuación, compila los binarios.

Esta guía incluye conceptos clave e instrucciones para los desarrolladores de ASP.NET Core. Si nunca ha usado Azure App Service, siga primero la guía de inicio rápido de ASP.NET Core y el tutorial de ASP.NET Core con SQL Database.

Mostrar las versiones del entorno de ejecución de .NET Core

En App Service, las instancias de Windows ya tienen instaladas todas las versiones compatibles de .NET Core. Para mostrar las versiones del SDK y .NET Core Runtime disponibles para usted, vaya a https://<app-name>.scm.azurewebsites.net/DebugConsole y ejecute el siguiente comando en la consola basada en el explorador:

dotnet --info

Mostrar la versión de .NET Core

Para mostrar la versión actual de .NET Core, ejecute el siguiente comando en Cloud Shell:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

Para mostrar todas las versiones compatibles de .NET Core, ejecute el siguiente comando en Cloud Shell:

az webapp list-runtimes --os linux | grep DOTNET

Establecer la versión de .NET Core

Establezca el marco de destino en el archivo de proyecto para el proyecto de ASP.NET Core. Para obtener más información, consulte Selección de la versión de .NET Core que se va a usar en la documentación de .NET Core.

Ejecute el siguiente comando en Cloud Shell para establecer la versión 3.1 de .NET Core:

az webapp config set --name <app-name> --resource-group <resource-group-name> --linux-fx-version "DOTNETCORE|3.1"

Personalización de la automatización de compilaciones

Si implementa la aplicación mediante paquetes Git o zip con la automatización de compilaciones activada, la automatización de compilaciones de App Service se ejecutará en este orden:

  1. Se ejecuta un script personalizado, si se especifica en PRE_BUILD_SCRIPT_PATH.
  2. Se ejecuta dotnet restore para restaurar las dependencias de NuGet.
  3. Se ejecuta dotnet publish para compilar un archivo binario para producción.
  4. Se ejecuta un script personalizado, si se especifica en POST_BUILD_SCRIPT_PATH.

PRE_BUILD_COMMAND y POST_BUILD_COMMAND son variables de entorno que, de forma predeterminada, están vacías. Para ejecutar comandos anteriores a la compilación, defina PRE_BUILD_COMMAND. Para ejecutar comandos posteriores a la compilación, defina POST_BUILD_COMMAND.

En el ejemplo siguiente se especifican las dos variables para una serie de comandos, separados por comas.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PRE_BUILD_COMMAND="echo foo, scripts/prebuild.sh"
az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings POST_BUILD_COMMAND="echo foo, scripts/postbuild.sh"

Para más variables de entorno para personalizar la automatización de compilaciones, consulte la configuración de Oryx.

Para más información acerca de cómo se ejecuta App Service y se compilan aplicaciones de ASP.NET Core en Linux, consulte el siguiente artículo de la documentación de Oryx sobre la detección y compilación de aplicaciones de .NET Core.

Acceso a variables de entorno

En App Service, puede establecer la configuración de la aplicación fuera del código de la aplicación. Después, puede tener acceso a ella en cualquier clase mediante el patrón de inserción de dependencias de ASP.NET Core estándar:

using Microsoft.Extensions.Configuration;

namespace SomeNamespace 
{
    public class SomeClass
    {
        private IConfiguration _configuration;
    
        public SomeClass(IConfiguration configuration)
        {
            _configuration = configuration;
        }
    
        public SomeMethod()
        {
            // retrieve nested App Service app setting
            var myHierarchicalConfig = _configuration["My:Hierarchical:Config:Data"];
            // retrieve App Service connection string
            var myConnString = _configuration.GetConnectionString("MyDbConnection");
        }
    }
}

Si configura una opción de aplicación con el mismo nombre en App Service y en appsettings.json, por ejemplo, el valor de App Service tiene prioridad sobre el valor de appsettings.json. El valor de appsettings.json local permite depurar la aplicación localmente, pero el valor de App Service permite ejecutar la aplicación en producción con la configuración de producción. Las cadenas de conexión funcionan de la misma manera. De este modo, puede conservar los secretos de aplicación fuera de su repositorio de código y tener acceso a los valores adecuados sin cambiar el código.

Nota

Tenga en cuenta que se accede a los datos de configuración jerárquica en appsettings.json mediante el delimitador __ (doble subrayado) que es estándar en Linux para .NET Core. Para invalidar una opción de configuración jerárquica específica en App Service, establezca el nombre de configuración de la aplicación con el mismo formato delimitado en la clave. Puede ejecutar el siguiente ejemplo en Cloud Shell:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings My__Hierarchical__Config__Data="some value"

Nota

Tenga en cuenta que el acceso a los datos de configuración jerárquica en appsettings.json se tiene mediante el delimitador : que es estándar para .NET Core. Para invalidar una opción de configuración jerárquica específica en App Service, establezca el nombre de configuración de la aplicación con el mismo formato delimitado en la clave. Puede ejecutar el siguiente ejemplo en Cloud Shell:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings My:Hierarchical:Config:Data="some value"

Implementar soluciones de varios proyectos

Cuando una solución de Visual Studio incluye varios proyectos, el proceso de publicación de Visual Studio ya incluye la selección del proyecto que se va a implementar. Al realizar la implementación en el motor de implementación de App Service, como con Git o con implementación de ZIP, con la automatización de compilaciones activada, el motor de implementación de App Service elige el primer sitio web o el proyecto de aplicación web que encuentra como aplicación de App Service. Para especificar el proyecto que App Service debe usar, especifique la configuración de la aplicación PROJECT. Por ejemplo, ejecute el siguiente comando en Cloud Shell:

az webapp config appsettings set --resource-group <resource-group-name> --name <app-name> --settings PROJECT="<project-name>/<project-name>.csproj"

Acceso a los registros de diagnóstico

ASP.NET Core proporciona un proveedor de registro integrado para App Service. En Program.cs del proyecto, agregue el proveedor a la aplicación a través del método de extensión de ConfigureLogging, como se muestra en el ejemplo siguiente:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.AddAzureWebAppDiagnostics();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Después, podrá configurar y generar registros con el patrón de .NET Core estándar.

Para acceder a los registros de la consola generados desde el código de la aplicación en App Service, active el registro de diagnósticos, para lo que debe ejecutar el siguiente comando en Cloud Shell:

az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging filesystem --level Verbose

Los valores posibles de --level son: Error, Warning, Info y Verbose. Todos los niveles incluyen el nivel anterior. Por ejemplo: Error incluye solo los mensajes de error, mientras que Verbose incluye todos los mensajes.

Una vez que se activa el registro de contenedor, ejecute el siguiente comando para ver la transmisión del registro:

az webapp log tail --resource-group <resource-group-name> --name <app-name>

Si no ve los registros de la consola de inmediato, vuelve a comprobarlo en 30 segundos.

Nota

También puede inspeccionar los archivos de registro desde el explorador en https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Para detener el streaming del registro en cualquier momento, escriba Ctrl+C.

Para obtener más información sobre cómo solucionar problemas de aplicaciones de ASP.NET Core en App Service, consulte Solución de problemas de ASP.NET Core en Azure App Service e IIS.

Obtener la página de excepciones detalladas

Cuando la aplicación de ASP.NET Core genera una excepción en el depurador de Visual Studio, el explorador muestra una página de excepciones detalladas, pero, en App Service, esa página se sustituye por un error genérico HTTP 500 o el mensaje Error al procesar la solicitud. Para mostrar la página de excepciones detalladas en App Service, agregue la configuración de aplicación ASPNETCORE_ENVIRONMENT a la aplicación con el siguiente comando en Cloud Shell.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings ASPNETCORE_ENVIRONMENT="Development"

Detección de sesión de HTTPS

En App Service, la terminación de TLS/SSL se produce en los equilibradores de carga de red, por lo que todas las solicitudes HTTPS llegan a la aplicación como solicitudes HTTP sin cifrar. Si necesita que la lógica de aplicación sepa si las solicitudes del usuario están cifradas o no, configure el middleware de encabezados reenviados en Startup.cs:

  • Configure el middleware con ForwardedHeadersOptions para reenviar los encabezados X-Forwarded-For y X-Forwarded-Proto en Startup.ConfigureServices.
  • Agregue intervalos de direcciones IP privadas a las redes conocidas, de modo que el middleware pueda confiar en el equilibrador de carga de App Service.
  • Invoque el método UseForwardedHeaders en Startup.Configure antes de invocar otro middleware.

Al colocar juntos los tres elementos, el código es similar al ejemplo siguiente:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        // These three subnets encapsulate the applicable Azure subnets. At the moment, it's not possible to narrow it down further.
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:10.0.0.0"), 104));
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:192.168.0.0"), 112));
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:172.16.0.0"), 108));
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseForwardedHeaders();

    ...

    app.UseMvc();
}

Para obtener más información, consulte Configuración de ASP.NET Core para trabajar con servidores proxy y equilibradores de carga.

Abrir sesión SSH en el explorador

Para que una sesión de SSH directa sea abierta con el contenedor, la aplicación debe estar en ejecución.

Pegue la siguiente dirección URL en el explorador y reemplace <app-name> por el nombre de la aplicación:

https://<app-name>.scm.azurewebsites.net/webssh/host

Si aún no está autenticado, será preciso que se autentique con su suscripción a Azure para conectarse. Una vez autenticado, verá un shell del explorador en el que puede ejecutar comandos dentro del contenedor.

SSH connection

Nota:

Los cambios que realice fuera del directorio /home se almacenan en el propio contenedor y no se conservan después del primer reinicio de la aplicación.

Para abrir una sesión remota de SSH desde un equipo local, consulte Abrir sesión SSH desde un shell remoto.

robots933456 en registros

Puede ver el mensaje siguiente en los registros del contenedor:

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

Puede omitir este mensaje sin problemas. /robots933456.txt es una ruta de acceso de la dirección URL ficticia que utiliza App Service para comprobar si el contenedor es capaz de atender las solicitudes. Una respuesta 404 simplemente indica que la ruta de acceso no existe, pero permite a App Service saber que el contenedor está en buen estado y listo para responder a las solicitudes.

Pasos siguientes

O bien, consulte más recursos:

Variables de entorno y configuración de la aplicación en Azure App Service