Migración de ASP.NET Core 5.0 a 6.0

En este artículo se explica cómo actualizar un proyecto de ASP.NET Core 5.0 existente a ASP.NET Core 6.0. Para obtener instrucciones sobre cómo migrar de ASP.NET Core 3.1 a ASP.NET Core 6.0, consulte Migración de ASP.NET Core 3.1 a 6.0.

Requisitos previos

Actualización de la versión del SDK de .NET en global.json

Si confía en un archivo global.json para tener como destino una versión específica del SDK de .NET, actualice la propiedad version a la versión del SDK de .NET 6.0 instalada. Por ejemplo:

{
  "sdk": {
-    "version": "5.0.100"
+    "version": "6.0.100"
  }
}

Actualización de la plataforma de destino

Actualizar el archivo del proyecto del Moniker de la plataforma de destino (TFM) a net6.0:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

</Project>

Actualización de las referencias del paquete

En el archivo del proyecto, actualice el atributo Version de cada referencia de paquete Microsoft.AspNetCore.* y Microsoft.Extensions.* a 6.0.0 o posterior. Por ejemplo:

<ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.3" />
-    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
+    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
</ItemGroup>

Nuevo modelo de hospedaje

El nuevo modelo de hospedaje mínimo de .NET 6 para aplicaciones de ASP.NET Core requiere solo un archivo y algunas líneas de código. Las aplicaciones que migran a la versión 6.0 no necesitan usar el nuevo modelo de hospedaje mínimo. Para obtener más información, consulte Las aplicaciones que migran a la versión 6.0 no necesitan usar el nuevo modelo de hospedaje mínimo en la sección siguiente.

El código siguiente de la plantilla ASP.NET Core vacía crea una aplicación con el nuevo modelo de hospedaje mínimo:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

El modelo de hospedaje mínimo:

  • Reducen considerablemente la cantidad de archivos y líneas de código que se necesitan para crear una aplicación. Solo se necesita un archivo con cuatro líneas de código.
  • Unifican Startup.cs y Program.cs en un archivo Program.cs único.
  • Utilizan instrucciones de nivel superior a fin de minimizar el código necesario para una aplicación.
  • Utilizan directivas using globales a fin de eliminar o minimizar la cantidad de líneas de instrucción using que se requieren.

En el código siguiente se muestran los archivos Startup.cs y Program.cs de una plantilla de aplicación web de ASP.NET Core 5 (Razor páginas) con instrucciones using sin usar eliminadas:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// Unused usings removed.

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

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

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

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
}
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
// Unused usings removed.

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

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

En ASP.NET Core 6, el código anterior se reemplaza por lo siguiente:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

En el ejemplo anterior de ASP.NET Core 6, se muestra cómo:

Más adelante, en este documento, se proporcionan ejemplos detallados de migración de código Startup ASP.NET Core 5 a ASP.NET Core 6 mediante el modelo de hospedaje mínimo.

Hay algunos cambios en los demás archivos generados para la plantilla de aplicación web:

- public string RequestId { get; set; }
+ public string? RequestId { get; set; }
  • Los valores predeterminados del nivel de registro han cambiado en appsettings.json y appsettings.Development.json:
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

En el código de plantilla de ASP.NET Core anterior, "Microsoft": "Warning" se cambió a "Microsoft.AspNetCore": "Warning". Este cambio provoca que se registren todos los mensajes informativos del espacio de nombres Microsoft, excepto Microsoft.AspNetCore. Por ejemplo, Microsoft.EntityFrameworkCore ahora se registra en el nivel informativo.

Para obtener más información sobre el nuevo modelo de hospedaje, consulte la sección Preguntas más frecuentes. Para obtener más información sobre la adopción de NRT y el análisis de estado nulo del compilador de .NET, consulte la sección Tipos de referencia que aceptan valores NULL (NRT) y análisis estático de estado NULL del compilador de .NET.

Las aplicaciones que migran a 6.0 o lo usan, y versiones posteriores, no necesitan usar el nuevo modelo de hospedaje mínimo

El uso de Startup y el host genérico usado por las plantillas de ASP.NET Core 3.1 y 5.0 son totalmente compatibles.

Uso de Startup con el nuevo modelo de hospedaje mínimo

Las aplicaciones de ASP.NET Core 3.1 y 5.0 pueden usar su código Startup con el nuevo modelo de hospedaje mínimo. El uso de Startup con el modelo de hospedaje mínimo tiene las siguientes ventajas:

  • No se usa ninguna reflexión oculta para llamar a la clase Startup.
  • El código asincrónico se puede escribir porque el desarrollador controla la llamada a Startup.
  • Se puede escribir código que intercale ConfigureServices y Configure.

Una limitación menor en el uso de código Startup con el nuevo modelo de hospedaje mínimo es que para insertar una dependencia en Configure, el servicio en Program.cs deberá resolverse manualmente.

Tenga en cuenta el código siguiente generado por la plantilla de páginas Razor de ASP.NET Core 3.1 o 5.0:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    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.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

El código anterior migrado al nuevo modelo de hospedaje mínimo:

using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, app.Environment);

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

    public IConfiguration Configuration { get; }

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

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

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

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

En el código anterior, el bloque if (env.IsDevelopment()) se quita porque, en modo de desarrollo, el middleware de la página de excepciones del desarrollador está habilitado de forma predeterminada. Para obtener más información, consulte Diferencias entre los modelos de hospedaje de ASP.NET Core 5 y 6 en la sección siguiente.

Al usar un contenedor de inserción de dependencias (DI) personalizado, agregue el código resaltado siguiente:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

// Using a custom DI container.
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(startup.ConfigureContainer);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.Run();
using Autofac;
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

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

    //  Using a custom DI container
    public void ConfigureContainer(ContainerBuilder builder)
    {
        // Configure custom container.
    }

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

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

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

Cuando se usa el modelo de hospedaje mínimo, el middleware de enrutamiento de puntos de conexión encapsula toda la canalización de middleware, por lo que no es necesario tener llamadas explícitas a UseRouting o UseEndpoints para registrar rutas. UseRouting todavía se puede usar para especificar dónde se produce la coincidencia de rutas, pero UseRouting no necesitará llamar explícitamente si las rutas deberían coincidir al principio de la canalización de middleware.

En el código siguiente, las llamadas a UseRouting y UseEndpoints se quitan de Startup. MapRazorPages es llamado por Program.cs:

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

    public IConfiguration Configuration { get; }

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

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        //app.UseRouting();

        //app.UseEndpoints(endpoints =>
        //{
        //    endpoints.MapRazorPages();
        //});
    }
}
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.MapRazorPages();

app.Run();

Al usar Startup con el nuevo modelo de hospedaje mínimo, tenga en cuenta la siguiente diferencia:

  • Program.cs controla la creación de instancias y la duración de la clase Startup.
  • Cualquier servicio adicional insertado en el método Configure debe resolverse manualmente por la clase Program.

Diferencias entre los modelos de hospedaje de ASP.NET Core 5 y 6

  • En el modo de desarrollo, el middleware de la página de excepciones del desarrollador está habilitado de forma predeterminada.
  • El nombre de la aplicación tiene como valor predeterminado el nombre del ensamblado del punto de entrada: Assembly.GetEntryAssembly().GetName().FullName. Cuando se use WebApplicationBuilder en una biblioteca, cambie explícitamente el nombre de la aplicación al ensamblado de la biblioteca para permitir que la detección de elementos de aplicación de MVC funcione. Consulte Cambio de la raíz del contenido, el nombre de la aplicación y el entorno en este documento para obtener instrucciones detalladas.
  • El middleware de enrutamiento de puntos de conexión encapsula toda la canalización de middleware, por lo que no es necesario tener llamadas explícitas a UseRouting o UseEndpoints para registrar rutas. UseRouting todavía se puede usar para especificar dónde se produce la coincidencia de rutas, pero UseRouting no necesitará llamar explícitamente si las rutas deberían coincidir al principio de la canalización de middleware.
  • La canalización se crea antes de que IStartupFilter se ejecute, por lo tanto, las excepciones causadas al compilar la canalización no son visibles para la cadena de llamadas IStartupFilter.
  • Algunas herramientas, como las migraciones de EF, usan Program.CreateHostBuilder para acceder al IServiceProvider de aplicaciones para ejecutar lógica personalizada en el contexto de la aplicación. Estas herramientas se han actualizado para usar una nueva técnica para ejecutar lógica personalizada en el contexto de la aplicación. Las migraciones de Entity Framework son un ejemplo de una herramienta que usa Program.CreateHostBuilder de esta manera. Estamos trabajando para asegurarnos de que las herramientas se actualicen para usar el nuevo modelo.
  • A diferencia de la clase Startup, el host mínimo no configura automáticamente un ámbito de inserción de dependencias al crear instancias del proveedor de servicios. Para los contextos en los que se requiere un ámbito, es necesario invocar IServiceScope con IServiceScopeFactory.CreateScope para crear instancias de un nuevo ámbito. Para obtener más información, consulte Procedimiento para resolver un servicio en el inicio de la aplicación.
  • No es posible cambiar ninguna configuración de host, como el nombre de la aplicación, el entorno o la raíz del contenido después de la creación de WebApplicationBuilder. Para obtener instrucciones detalladas sobre cómo cambiar la configuración del host, consulte Personalización IHostBuilder o IWebHostBuilder. Las siguientes API resaltadas producen una excepción:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

// WebHost

try
{
    builder.WebHost.UseContentRoot(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ApplicationKey, "ApplicationName2");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ContentRootKey, Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.EnvironmentKey, Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

// Host
try
{
    builder.Host.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    // TODO: This does not throw
    builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
  • La clase Startup no se puede usar desde WebApplicationBuilder.Host ni WebApplicationBuilder.WebHost. El código resaltado siguiente produce una excepción:

    var builder = WebApplication.CreateBuilder(args);
    
    try
    {
        builder.Host.ConfigureWebHostDefaults(webHostBuilder =>
        {
            webHostBuilder.UseStartup<Startup>();
        });
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;    
    }
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
    var builder = WebApplication.CreateBuilder(args);
    
    try
    {
        builder.WebHost.UseStartup<Startup>();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;    
    }
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
  • La implementación de IHostBuilder en WebApplicationBuilder (WebApplicationBuilder.Host), no aplaza la ejecución de los métodos ConfigureServices, ConfigureAppConfiguration o ConfigureHostConfiguration. No aplazar la ejecución permite que el código use WebApplicationBuilder para observar los cambios realizados en IServiceCollection y IConfiguration. En el ejemplo siguiente solo se agrega Service1 como IService:

    using Microsoft.Extensions.DependencyInjection.Extensions;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Host.ConfigureServices(services =>
    {
        services.TryAddSingleton<IService, Service1>();
    });
    
    builder.Services.TryAddSingleton<IService, Service2>();
    
    var app = builder.Build();
    
    // Displays Service1 only.
    Console.WriteLine(app.Services.GetRequiredService<IService>());
    
    app.Run();
    
    class Service1 : IService
    {
    }
    
    class Service2 : IService
    {
    }
    
    interface IService
    {
    }
    

En el código anterior, la devolución de llamada builder.Host.ConfigureServices se llama insertada en lugar de aplazarse hasta que se llame a builder.Build. Esto significa que Service1 se agrega al IServiceCollection antes que Service2 y da como resultado que Service1 se resuelva para IService.

Compilación de bibliotecas para ASP.NET Core 6

El ecosistema de .NET existente creó extensibilidad en torno a IServiceCollection, IHostBuilder y IWebHostBuilder. Estas propiedades están disponibles en WebApplicationBuilder como Services, Host y WebHost.

WebApplication implementa Microsoft.AspNetCore.Builder.IApplicationBuilder y Microsoft.AspNetCore.Routing.IEndpointRouteBuilder.

Esperamos que los autores de bibliotecas sigan teniendo como destino IHostBuilder, IWebHostBuilder, IApplicationBuilder y IEndpointRouteBuilder al compilar componentes específicos de ASP.NET Core. Esto garantiza que el middleware, el controlador de rutas u otros puntos de extensibilidad sigan funcionando en diferentes modelos de hospedaje.

Preguntas más frecuentes

  • ¿Es el nuevo modelo de hospedaje mínimo menos capaz?

    No. El nuevo modelo de hospedaje es funcionalmente equivalente al 98 % de los escenarios admitidos por IHostBuilder y IWebHostBuilder. Hay algunos escenarios avanzados que requieren soluciones alternativas específicas en IHostBuilder, pero esperamos que sean extremadamente raros.

  • ¿Está en desuso el modelo de hospedaje genérico?

    No. El modelo de hospedaje genérico es un modelo alternativo que se admite indefinidamente. El host genérico respalda el nuevo modelo de hospedaje y sigue siendo la forma principal de hospedar aplicaciones basadas en trabajo.

  • ¿Tengo que migrar al nuevo modelo de hospedaje?

    No. El nuevo modelo de hospedaje es la manera preferida de hospedar nuevas aplicaciones con .NET 6 y versiones posteriores, pero no está obligado a cambiar el diseño del proyecto en las aplicaciones existentes. Esto significa que las aplicaciones pueden actualizar de .NET 5 a .NET 6 cambiando la plataforma de destino del archivo del proyecto de net5.0 a net6.0. Para obtener más información, consulte la sección Actualizar la plataforma de destino de este artículo. Sin embargo, se recomienda que las aplicaciones migren al nuevo modelo de hospedaje para sacar partido a las nuevas características que solo están disponibles para el nuevo modelo de hospedaje.

  • ¿Tengo que usar instrucciones de nivel superior?

    No. Todas las plantillas de proyecto nuevas usan instrucciones de nivel superior, pero las nuevas API de hospedaje se pueden usar en cualquier aplicación de .NET 6 para hospedar un servidor web o una aplicación web.

  • ¿Dónde se pone el estado almacenado como campos, en mi clase Program o Startup?

    Se recomienda encarecidamente usar la inserción de dependencias (DI) para fluir el estado en aplicaciones de ASP.NET Core.

    Hay dos enfoques para almacenar el estado fuera de la DI:

    • Almacene el estado en otra clase. Al almacenar en una clase se supone un estado estático al que se puede acceder desde cualquier lugar de la aplicación.

    • Use la clase Program generada por instrucciones de nivel superior para almacenar el estado. El uso de Program para almacenar el estado es el enfoque semántico:

      var builder = WebApplication.CreateBuilder(args);
      
      ConfigurationValue = builder.Configuration["SomeKey"] ?? "Hello";
      
      var app = builder.Build();
      
      app.MapGet("/", () => ConfigurationValue);
      
      app.Run();
      
      partial class Program
      {
          public static string? ConfigurationValue { get; private set; }
      }
      
  • ¿Qué ocurre si estaba usando un contenedor de inserción de dependencias personalizado?

    Se admiten contenedores de DI personalizados. Para obtener un ejemplo, consulte Contenedor de inserción de dependencias (DI) personalizado.

  • ¿Siguen WebApplicationFactory y TestServer funcionando?

    Sí. WebApplicationFactory<TEntryPoint> es la manera de probar el nuevo modelo de hospedaje. Para obtener un ejemplo, consulte Probar con WebApplicationFactory o TestServer.

Blazor

Después de seguir las instrucciones anteriores de este artículo para actualizar una aplicación a la versión 6.0, adopte características específicas siguiendo los vínculos de Novedades de ASP.NET Core 6.0.

Para adoptar todas las nuevas características de la versión 6.0 para aplicacionesBlazor, se recomienda el siguiente proceso:

  • Cree un nuevo proyecto de Blazor 6.0 a partir de una de las plantillas de proyecto de Blazor. Para más información, vea Herramientas para ASP.NET Core Blazor.
  • Mueva los componentes y el código de la aplicación a la aplicación 6.0 realizando modificaciones para adoptar las nuevas características de la versión 6.0.

Migración de proyectos de SPA

Migración de aplicaciones Angular desde extensiones de SPA

Consulte esta incidencia de GitHub

Migración de aplicaciones React desde extensiones de SPA

Consulte Migración de aplicaciones React desde extensiones de SPA en esta incidencia de GitHub

Actualización de imágenes de Docker

En el caso de aplicaciones que usen Docker, actualice las instrucciones y los scripts de DockerfileFROM. Use una imagen de base que incluya el entorno de ejecución de ASP.NET Core 6.0. Tenga en cuenta la siguiente diferencia de comandos de docker pull entre ASP.NET Core 5.0 y 6.0:

- docker pull mcr.microsoft.com/dotnet/aspnet:5.0
+ docker pull mcr.microsoft.com/dotnet/aspnet:6.0

Consulta la incidencia de GitHub Cambio importante: formato predeterminado del registrador de consola establecido en JSON.

Cambios en el SDK de ASP.NET Core Razor

El compilador Razor ahora aprovecha la nueva característica de generadores de origen para generar archivos C# compilados a partir de las vistas y páginas de Razor de un proyecto. En versiones anteriores:

  • La compilación se basaba en los destinos RazorGenerate y RazorCompile para generar el código generado. Estos destinos ya no son válidos. En .NET 6, tanto la generación de código como la compilación son compatibles con una sola llamada al compilador. RazorComponentGenerateDependsOn todavía se admite para especificar las dependencias necesarias antes de que se ejecute la compilación.
  • Se generó un ensamblado Razor independiente, AppName.Views.dll, que contenía los tipos de vista compilados en una aplicación. Este comportamiento está en desuso y se genera un único ensamblado AppName.dll que contiene los tipos de aplicación y las vistas generadas.
  • Los tipos de aplicación de AppName.Views.dll eran públicos. En .NET 6, los tipos de aplicación están en AppName.dll, pero son internal sealed. Las aplicaciones que realizan la detección de tipos en AppName.Views.dll no podrán realizar la detección de tipos en AppName.dll. A continuación, se muestra el cambio de API:
- public class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
+ internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>

Realice los cambios siguientes:

  • Las siguientes propiedades ya no son aplicables con el modelo de compilación de un solo paso.
    • RazorTargetAssemblyAttribute
    • RazorTargetName
    • EnableDefaultRazorTargetAssemblyInfoAttributes
    • UseRazorBuildServer
    • GenerateRazorTargetAssemblyInfo
    • GenerateMvcApplicationPartsAssemblyAttributes

Para obtener más información, consulte el compilador de Razor ya no genera un ensamblado de Vistas.

Las plantillas de proyecto usan Duende Identity Server

Las plantillas de proyecto ahora usan Duende Identity Server.

Importante

Duende Identity Server es un producto de código abierto con un contrato de licencia recíproca. Si tiene previsto usar Duende Identity Server en producción, es posible que tenga que obtener una licencia comercial de Duende Software y pagar una cuota de licencia. Para obtener más información, consulte Duende Software: licencias.

Para obtener información sobre cómo usar Microsoft Azure Active Directory para ASP.NET Core Identity, consulte Identity (repositorio de GitHub dotnet/aspnetcore).

Agregue una propiedad DbSet<Key> denominada Keys a cada IdentityDbContext para satisfacer un nuevo requisito de la versión actualizada de IPersistedGrantDbContext. Las claves son necesarias como parte del contrato con los almacenes de Duende Identity Server.

public DbSet<Key> Keys { get; set; }

Nota:

Las migraciones existentes deben volver a crearse para Duende Identity Server.

Ejemplos de código migrados a ASP.NET Core 6.0

Ejemplos de código migrados al nuevo modelo de hospedaje mínimo en 6.0

Revisar cambios importantes

Consulte los siguientes recursos:

Tipos de referencia que aceptan valores NULL (NRT) y análisis estático de estado NULL del compilador de .NET

Las plantillas de proyectos ASP.NET Core usan tipos de referencia que aceptan valores NULL (NRT) y el compilador de .NET realiza análisis estáticos de estado NULL. Estas características se publicaron con C# 8 y están habilitadas de forma predeterminada para las aplicaciones generadas con ASP.NET Core 6.0 (C# 10) o versiones posteriores.

Las advertencias de análisis estático de estado NULL del compilador de .NET pueden servir como guía para actualizar un ejemplo de documentación o una aplicación de ejemplo localmente, o bien se pueden ignorar. El análisis estático de estado NULL se puede deshabilitar estableciendo Nullable en disable en el archivo de proyecto de la aplicación, algo que solo se recomienda para ejemplos de documentación y aplicaciones de ejemplo si las advertencias del compilador distraen durante el aprendizaje sobre .NET. No se recomienda deshabilitar la comprobación de estado NULL en proyectos de producción.

Para obtener más información sobre las NRT, la propiedad Nullable de MSBuild y las aplicaciones de actualización (incluidas las instrucciones #pragma), consulte los siguientes recursos en la documentación de C#:

Módulo de ASP.NET Core (ANCM)

Si el módulo de ASP.NET Core (ANCM) no era un componente seleccionado cuando Visual Studio se instaló o si se instaló una versión anterior de ANCM en el sistema, descargue el instalador de agrupación de hospedaje de .NET Core más reciente (descarga directa) y ejecute el instalador. Para obtener más información, consulte Agrupación de hospedaje.

Cambio de nombre de la aplicación

En .NET 6, WebApplicationBuilder normaliza la ruta de acceso raíz del contenido para finalizar con DirectorySeparatorChar. La mayoría de las aplicaciones que migran desde HostBuilder o WebHostBuilder no tendrán el mismo nombre de aplicación porque no se normalizan. Para obtener más información, consulte SetApplicationName

Recursos adicionales