Migración de ASP.NET Core 2.0 a 2.1

Por Rick Anderson

Consulta Novedades de ASP.NET Core 2.1 para obtener una descripción general de las nuevas funciones de ASP.NET Core 2.1.

Este artículo:

  • Cubre los aspectos básicos de la migración de una aplicación ASP.NET Core 2.0 a 2.1.
  • Proporciona información general sobre los cambios realizados en las plantillas de aplicación web de ASP.NET Core.

Una forma rápida de hacerse una idea general de los cambios de la 2.1 es:

  • Crear una aplicación web ASP.NET Core 2.0 denominada WebApp1.
  • Confirmar WebApp1 en un sistema de control de código fuente.
  • Eliminar WebApp1 y crear una aplicación web ASP.NET Core 2.1 denominada WebApp1 en el mismo lugar.
  • Revisar los cambios en la versión 2.1.

En este artículo se proporciona información general sobre la migración a ASP.NET Core 2.1. No contiene una lista completa de todos los cambios necesarios para migrar a la versión 2.1. Algunos proyectos pueden requerir más pasos en función de las opciones seleccionadas cuando se creó el proyecto y las modificaciones realizadas en el proyecto.

Actualización del archivo de proyecto para que use las versiones 2.1

Actualización del archivo del proyecto:

  • Cambiar la plataforma de destino a .NET Core 2.1 mediante la actualización del archivo de proyecto a <TargetFramework>netcoreapp2.1</TargetFramework>.
  • Reemplazar la referencia de paquete para por Microsoft.AspNetCore.All una referencia de paquete para Microsoft.AspNetCore.App. Es posible que tengas que agregar dependencias que se quitaron de Microsoft.AspNetCore.All. Para obtener más información, consulta Metapaquete Microsoft.AspNetCore.All para ASP.NET Core 2.0 y Microsoft.AspNetCore.App metapaquete para ASP.NET Core.
  • Quita el atributo "Version" en la referencia del paquete a Microsoft.AspNetCore.App. Los proyectos que usan <Project Sdk="Microsoft.NET.Sdk.Web"> no necesitan establecer la versión. La versión está implícita en el marco de destino y se selecciona para que coincida mejor con la manera en que funciona ASP.NET Core 2.1. Para obtener más información, consulta la sección Reglas para proyectos destinados al marco compartido.
  • En el caso de las aplicaciones destinadas a .NET Framework, actualiza cada referencia de paquete a la versión 2.1.
  • Quita las referencias a <los elementos DotNetCliToolReference> para los siguientes paquetes. Estas herramientas se agrupan de forma predeterminada en la CLI de .NET y no es necesario instalarlas por separado.
    • Microsoft.DotNet.Watcher.Tools (dotnet watch)
    • Microsoft.EntityFrameworkCore.Tools.DotNet (dotnet ef)
    • Microsoft.Extensions.Caching.SqlConfig.Tools (dotnet sql-cache)
    • Microsoft.Extensions.SecretManager.Tools (dotnet user-secrets)
  • Opcional: puedes quitar el <elemento DotNetCliToolReference> para Microsoft.VisualStudio.Web.CodeGeneration.Tools. Puedes reemplazar esta herramienta por una versión instalada globalmente ejecutando dotnet tool install -g dotnet-aspnet-codegenerator.
  • Para la versión 2.1, una biblioteca de clases de Razor es la solución recomendada para distribuir archivos Razor. Si la aplicación usa vistas incrustadas o, de lo contrario, se basa en la compilación en tiempo de ejecución de Razor los archivos, agrega <CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory> a un <PropertyGroup> en el archivo del proyecto.

El marcado siguiente muestra el archivo de proyecto 2.0 generado por la plantilla:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <UserSecretsId>aspnet-{Project Name}-{GUID}</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.3" PrivateAssets="All" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.4" PrivateAssets="All" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.3" />
    <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.2" />
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.4" />
  </ItemGroup>
</Project>

El marcado siguiente muestra el archivo de proyecto 2.1 generado por la plantilla:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <UserSecretsId>aspnet-{Project Name}-{GUID}</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" PrivateAssets="All" />
  </ItemGroup>

</Project>

Reglas para proyectos destinados al marco compartido

Un marco compartido es un conjunto de ensamblados (archivos .dll) que no están en las carpetas de la aplicación. El marco de trabajo compartido debe instalarse en la máquina para ejecutar la aplicación. Para obtener más información, consulta este artículo sobre el marco de trabajo compartido.

ASP.NET Core 2.1 incluye los siguientes marcos compartidos:

La versión especificada por la referencia del paquete es la versión mínima necesaria. Por ejemplo, un proyecto que haga referencia a las versiones 2.1.1 de estos paquetes no se ejecutará en un equipo con solo el entorno de ejecución 2.1.0 instalado.

Problemas conocidos de proyectos destinados a un marco compartido:

  • El SDK de .NET Core 2.1.300 (incluido por primera vez en Visual Studio 15.6) establece la versión implícita de Microsoft.AspNetCore.App en 2.1.0 que provocó conflictos con Entity Framework Core 2.1.1. La solución recomendada es actualizar el SDK de .NET Core a la versión 2.1.301 o posterior. Para obtener más información, consulta Paquetes que comparten dependencias con Microsoft.AspNetCore.App no pueden hacer referencia a versiones de revisión.

  • Todos los proyectos que deben usar Microsoft.AspNetCore.All o Microsoft.AspNetCore.App deben agregar una referencia de paquete para el paquete en el archivo del proyecto, incluso si contienen una referencia de proyecto a otro proyecto mediante Microsoft.AspNetCore.All o Microsoft.AspNetCore.App.

    Ejemplo:

    • MyApptiene una referencia al paqueteMicrosoft.AspNetCore.App.
    • MyApp.Tests tiene una referencia de proyecto a MyApp.csproj.

    Agrega una referencia de paquete para Microsoft.AspNetCore.App a MyApp.Tests. Para obtener más información, consulta Pruebas de integración difíciles de configurar y puede interrumpir el mantenimiento del marco compartido.

Actualización a las imágenes de Docker 2.1

En ASP.NET Core 2.1, las imágenes de Docker se migran al repositorio dotnet/dotnet-docker de GitHub. En la tabla siguiente se muestran los cambios en la etiqueta y la imagen de Docker:

2.0 2.1
microsoft/aspnetcore:2.0 microsoft/dotnet:2.1-aspnetcore-runtime
microsoft/aspnetcore-build:2.0 microsoft/dotnet:2.1-sdk

Cambia las líneas FROM del Dockerfile para utilizar los nuevos nombres y etiquetas de imagen de la columna 2.1 de la tabla anterior. Para obtener más información, consulta Migración desde repositorios de Docker de aspnetcore a dotnet.

Cambios en Main

Las imágenes siguientes muestran los cambios realizados en el archivo generado Program.cs con plantilla.

diferencias entre versiones anteriores

La imagen anterior muestra la versión 2.0 con las eliminaciones en rojo.

La siguiente imagen muestra el código 2.1. El código de color verde reemplazó la versión 2.0:

diferencias entre las nuevas versiones

El siguiente código muestra la versión 2.1 de Program.cs:

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

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

El nuevo Main reemplaza la llamada a BuildWebHost con CreateWebHostBuilder. IWebHostBuilder se agregó para admitir una nueva infraestructura de prueba de integración.

Cambios en Startup

En el código siguiente se muestran los cambios en el código generado por la plantilla 2.1. Todos los cambios se agregan recientemente, excepto que UseBrowserLink se han quitado:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

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

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            // If the app uses Session or TempData based on Session:
            // app.UseSession();

            app.UseMvc();
        }
    }
}

Los cambios de código anteriores se detallan en:

Cambios en el código de autenticación

ASP.NET Core 2.1 proporciona ASP.NET Core Identity como una biblioteca de clases de Razor (RCL).

La interfaz de usuario predeterminada 2.1 Identity no proporciona actualmente características nuevas significativas en la versión 2.0. Reemplazar por Identity el paquete RCL es opcional. Entre las ventajas de reemplazar el código generado por la plantilla con Identity la versión RCL se incluyen las siguientes:

  • Muchos archivos se mueven fuera del árbol de origen.
  • Las correcciones de errores o las nuevas características que se van a Identity incluir en el metapaquete de Microsoft.AspNetCore.App. Obtienes automáticamente la actualización Identity cuando Microsoft.AspNetCore.App se actualiza.

Si has realizado cambios no triviales en el código generado por Identity la plantilla:

  • Las ventajas anteriores probablemente no justifican la conversión a la versión RCL.
  • Puedes mantener el código ASP.NET Core 2.0Identity, que es totalmente compatible.

Identity 2.1 expone puntos de conexión con el Identity área. Por ejemplo, en la tabla siguiente se muestran ejemplos de puntos de Identity conexión que cambian de 2.0 a 2.1:

Dirección URL 2.0 Dirección URL 2.1
/Account/Login /Identity/Account/Login
/Account/Logout /Identity/Account/Logout
/Account/Manage /Identity/Account/Manage

Las aplicaciones que tienen código mediante Identity y reemplazan la interfaz de usuario 2.0 Identity por la biblioteca 2.1 Identity deben tener en cuenta Identity las direcciones URL tienen /Identity un segmento antepuesto a los URI. Una manera de controlar los nuevos Identity puntos de conexión es configurar redireccionamientos, por ejemplo, de /Account/Login a /Identity/Account/Login.

Actualizar Identity a versión 2.1

Existen las siguientes opciones para actualizar Identity a 2.1.

  • Usa el Identity código de la interfaz de usuario 2.0 sin cambios. El uso Identity del código UI 2.0 es totalmente compatible. Este es un buen enfoque cuando se han realizado cambios significativos en el Identity código generado.
  • Elimina el código 2.0 existente Identity y ScaffoldIdentity en el proyecto. El proyecto usará el ASP.NET Core IdentityRazorClass Library. Puedes generar código y interfaz de usuario para cualquiera de los códigos de interfaz de usuario Identity que modificaste. Aplica los cambios de código al código de interfaz de usuario reciente con scaffolded.
  • Elimina el código Identity 2.0 existente y Scaffold Identity en el proyecto con la opción Reemplazar todos los archivos.

Reemplaza la interfaz de usuario Identity 2.0 por la biblioteca de clases deRazor Identity 2.1

En esta sección se describen los pasos para reemplazar el código Identity generador por plantilla de ASP.NET Core 2.0 por la biblioteca de clases de RazorASP.NET Core Identity. Los pasos siguientes son para un Razor proyecto de Pages, pero el enfoque de un proyecto de MVC es similar.

  • Comprueba que el archivo del proyecto se ha actualizado para usar las versiones 2.1
  • Elimina las siguientes carpetas y todos los archivos de ellos:
    • Controladores
    • Pages/Account/
    • Extensiones
  • Compila el proyecto.
  • Scaffold Identityen tu proyecto:
    • Selecciona el archivo_Layout.cshtmlque sale del proyecto.
    • Selecciona el + icono del lado derecho de la clase de contexto de datos. Aceptar el nombre predeterminado.
    • Selecciona Agregar para crear una nueva clase de contexto Datos. Es necesario crear un nuevo contexto de datos para el scaffold. Quita el nuevo contexto de datos en la sección siguiente.

Actualización tras del scaffolding Identity

  • Elimina la Identity clase derivada generada por scaffolderIdentityDbContexten la carpeta Areas/Identity/Data/.

  • Elimina Areas/Identity/IdentityHostingStartup.cs.

  • Actualiza el archivo _LoginPartial.cshtml:

    • Mueve Pages/_LoginPartial.cshtml a Pages/Shared/_LoginPartial.cshtml.
    • Agrega asp-area="Identity" a los vínculos de formulario y delimitador.
    • Actualiza el <form /> elemento a <form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/Index", new { area = "" })" method="post" id="logoutForm" class="navbar-right">.

    En el código siguiente se muestra el archivo _LoginPartial.cshtml actualizado.

    @using Microsoft.AspNetCore.Identity
    
    @inject SignInManager<ApplicationUser> SignInManager
    @inject UserManager<ApplicationUser> UserManager
    
    @if (SignInManager.IsSignedIn(User))
    {
        <form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/Index", new { area = "" })" method="post" id="logoutForm" class="navbar-right">
            <ul class="nav navbar-nav navbar-right">
                <li>
                    <a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
                </li>
                <li>
                    <button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button>
                </li>
            </ul>
        </form>
    }
    else
    {
        <ul class="nav navbar-nav navbar-right">
            <li><a asp-area="Identity" asp-page="/Account/Register">Register</a></li>
            <li><a asp-area="Identity" asp-page="/Account/Login">Log in</a></li>
        </ul>
    }
    

Actualiza ConfigureServices con el siguiente código:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<ApplicationUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc();

    // Register no-op EmailSender used by account confirmation and password reset 
    // during development
    services.AddSingleton<IEmailSender, EmailSender>();
}

Cambios en los Razor archivos de proyectos Razor de Pages

El archivo de diseño

  • Mover Pages/_Layout.cshtml a Pages/Shared/_Layout.cshtml

  • En Areas/Identity/Pages/_ViewStart.cshtml, cambie Layout = "/Pages/_Layout.cshtml" a Layout = "/Pages/Shared/_Layout.cshtml".

  • El archivo _Layout.cshtml tiene los siguientes cambios:

    • <partial name="_CookieConsentPartial" /> es añadido. Para más información, vea GDPR support in ASP.NET Core (Compatibilidad con el Reglamento general de protección de datos en ASP.NET Core).
    • jQuery cambia de 2.2.0 to 3.3.1.

_ValidationScriptsPartial.cshtml

  • Pages/_ValidationScriptsPartial.cshtml se mueve a Pages/Shared/_ValidationScriptsPartial.cshtml.
  • jquery.validate/1.14.0 cambia a jquery.validate/1.17.0.

Nuevos archivos

Se añaden los siguientes archivos:

  • Privacy.cshtml
  • Privacy.cshtml.cs

Consulte compatibilidad con RGPD en ASP.NET Core para obtener información sobre los archivos anteriores.

Cambios en los archivos de proyectos Razor de MVC

El archivo de diseño

El Layout.cshtml archivo presenta los siguientes cambios:

  • <partial name="_CookieConsentPartial" /> es añadido.
  • jQuery cambia de 2.2.0 to 3.3.1

_ValidationScriptsPartial.cshtml

jquery.validate/1.14.0 cambia a jquery.validate/1.17.0

Nuevos archivos y métodos de acción

Se agregan los siguientes:

  • Views/Home/Privacy.cshtml
  • El Privacy método de acción se añade al Home controlador.

Consulte compatibilidad con RGPD en ASP.NET Core para obtener información sobre los archivos anteriores.

Cambios en el archivo launchSettings.json

Como ASP.NET Core aplicaciones que ahora usan HTTPS de forma predeterminada, el Properties/launchSettings.json archivo ha cambiado.

El siguiente JSON muestra el archivo launchSettings.json generado por la plantilla 2.0 anterior:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:1799/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "WebApp1": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:1798/"
    }
  }
}

El siguiente JSON muestra el nuevo archivo launchSettings.json generado por la plantilla 2.1:

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

Para más información, vea Aplicación de HTTPS en ASP.NET Core.

Últimos cambios

Encabezado fileResult Range

FileResult ya no procesa el encabezado Accept-Ranges de forma predeterminada. Para habilitar la Accept-Ranges cabecera, ajuste EnableRangeProcessing a true.

Encabezado ControllerBase.File y PhysicalFile Range

Los métodos siguientes ControllerBase ya no procesan el encabezado Accept-Ranges de forma predeterminada:

Para habilitar el Accept-Ranges encabezado, establezca el EnableRangeProcessing parámetro en true.

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.

Cambios adicionales