Migración de ASP.NET Core 1.x a 2.0
Por Scott Addie
En este artículo se le guía a lo largo del proceso de actualización de un proyecto existente de ASP.NET Core 1.x a ASP.NET Core 2.0. La migración de la aplicación a ASP.NET Core 2.0 permite aprovechar muchas características nuevas y mejoras de rendimiento.
Las aplicaciones existentes de ASP.NET Core 1.x se basan en plantillas de proyecto específicas de la versión. A medida que el marco de trabajo de ASP.NET Core evoluciona, también lo hacen las plantillas de proyecto y el código de inicio incluido en ellas. Además de actualizar el marco de trabajo de ASP.NET Core, debe actualizar el código de la aplicación.
Requisitos previos
Consulte Introducción a ASP.NET Core.
Actualización del moniker de la plataforma de destino (TFM)
Los proyectos para .NET Core deben usar el TFM de una versión mayor o igual que .NET Core 2.0. Busque el nodo <TargetFramework>
del archivo .csproj
y reemplace su texto interno por netcoreapp2.0
:
<TargetFramework>netcoreapp2.0</TargetFramework>
Los proyectos para .NET Framework deben usar el TFM de una versión mayor o igual que .NET Framework 4.6.1. Busque el nodo <TargetFramework>
del archivo .csproj
y reemplace su texto interno por net461
:
<TargetFramework>net461</TargetFramework>
Nota
.NET Core 2.0 ofrece un área expuesta mucho mayor que .NET Core 1.x. Si el destino es .NET Framework solo porque faltan API en .NET Core 1.x, el uso de .NET Core 2.0 como destino es probable que dé resultado.
Si el archivo de proyecto contiene <RuntimeFrameworkVersion>1.{sub-version}</RuntimeFrameworkVersion>
, consulte este problema de GitHub.
Actualización de la versión del SDK de .NET Core en global.json
Si la solución se basa en un archivo global.json para que el destino sea una versión específica del SDK de .NET Core, actualice su propiedad version
para usar la versión 2.0 instalada en el equipo:
{
"sdk": {
"version": "2.0.0"
}
}
Actualización de las referencias del paquete
El archivo .csproj
de un proyecto de 1.x enumera cada paquete NuGet usado por el proyecto.
En un proyecto de ASP.NET Core 2.0 para .NET Core 2.0, una sola referencia de metapaquete del archivo .csproj
reemplaza a la colección de paquetes:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
</ItemGroup>
Todas las características de ASP.NET Core 2.0 y Entity Framework Core 2.0 están incluidas en el metapaquete.
Los proyectos de ASP.NET Core 2.0 para .NET Framework deben seguir haciendo referencia a paquetes NuGet individuales. Actualización del atributo Version
de cada nodo <PackageReference />
a 2.0.0.
Por ejemplo, esta es la lista de nodos <PackageReference />
usados en un proyecto típico de ASP.NET Core 2.0 para .NET Framework:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" />
</ItemGroup>
El paquete Microsoft.Extensions.CommandLineUtils
se ha retirado. Sigue estando disponible, pero sin compatibilidad.
Actualización de las herramientas de la CLI de .NET
En el archivo .csproj
, actualice el atributo Version
de cada nodo <DotNetCliToolReference />
a 2.0.0.
Por ejemplo, esta es la lista de herramientas de la CLI usadas en un proyecto típico de ASP.NET Core 2.0 para .NET Core 2.0:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>
Cambio de nombre de la propiedad Package Target Fallback
El archivo .csproj
de un proyecto de 1.x usa un nodo PackageTargetFallback
y una variable:
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
Cambie el nombre del nodo y la variable a AssetTargetFallback
:
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
Actualización del método Main de Program.cs
En los proyectos de 1.x, el método Main
de Program.cs
tenía este aspecto:
using System.IO;
using Microsoft.AspNetCore.Hosting;
namespace AspNetCoreDotNetCore1App
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
}
En los proyectos de 2.0, el método Main
de Program.cs
se ha simplificado:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
namespace AspNetCoreDotNetCore2App
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
La adopción de este nuevo patrón 2.0 es muy recomendable y necesaria para que funcionen características de producto como las migraciones de Entity Framework (EF) Core. Por ejemplo, la ejecución de Update-Database
desde la ventana Consola del Administrador de paquetes o de dotnet ef database update
desde la línea de comandos (en proyectos convertidos a ASP.NET Core 2.0) genera el error siguiente:
Unable to create an object of type '<Context>'. Add an implementation of 'IDesignTimeDbContextFactory<Context>' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
Incorporación de proveedores de configuración
En los proyectos de 1.x, la incorporación de proveedores de configuración a una aplicación se lograba a través del constructor Startup
. Para ello, era necesario crear una instancia de ConfigurationBuilder
, cargar los proveedores aplicables (variables de entorno, configuración de la aplicación, etc.) e inicializar un miembro de IConfigurationRoot
.
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
builder.AddUserSecrets<Startup>();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
En el ejemplo anterior se carga el miembro Configuration
con opciones de configuración de appsettings.json
, así como cualquier archivo appsettings.{Environment}.json
que coincida con la propiedad IHostingEnvironment.EnvironmentName
. La ubicación de estos archivos está en la misma ruta de acceso que Startup.cs
.
En los proyectos de 2.0, el código de configuración reutilizable inherente a los proyectos de 1.x se ejecuta en segundo plano. Por ejemplo, las variables de entorno y la configuración de la aplicación se cargan durante el inicio. El código de Startup.cs
equivalente se reduce a la inicialización de IConfiguration
con la instancia insertada:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
Para quitar los proveedores predeterminados que WebHostBuilder.CreateDefaultBuilder
agrega, invoque el método Clear
en la propiedad IConfigurationBuilder.Sources
dentro de ConfigureAppConfiguration
. Para volver a agregar proveedores, use el método ConfigureAppConfiguration
en Program.cs
:
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostContext, config) =>
{
// delete all default configuration providers
config.Sources.Clear();
config.AddJsonFile("myconfig.json", optional: true);
})
.Build();
La configuración que el método CreateDefaultBuilder
utiliza en el fragmento de código anterior puede verse aquí.
Para más información, consulte Configuración en ASP.NET Core.
Mover el código de inicialización de la base de datos
En proyectos de 1.x que usen EF Core 1.x, un comando como dotnet ef migrations add
hace lo siguiente:
- Crea una instancia de
Startup
. - Invoca el método
ConfigureServices
para registrar todos los servicios de la inserción de dependencias (como los tiposDbContext
). - Realiza las tareas necesarias.
En proyectos 2.0 que usen EF Core 2.0, se invoca Program.BuildWebHost
para obtener los servicios de aplicación. A diferencia de 1.x, se invoca Startup.Configure
como efecto secundario adicional. Si la aplicación 1.x ha invocado el código de inicialización de la aplicación en el método Configure
, pueden producirse errores inesperados. Por ejemplo, si todavía no existe la base de datos, el código de propagación se ejecuta antes que el comando EF Core Migrations. Este problema provocará un error en un comando dotnet ef migrations list
si la base de datos no existe.
Tenga en cuenta el código de propagación 1.x siguiente en el método Configure
de Startup.cs
:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
SeedData.Initialize(app.ApplicationServices);
En los proyectos 2.0, mueva la llamada SeedData.Initialize
al método Main
de Program.cs
:
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
// Requires using RazorPagesMovie.Models;
SeedData.Initialize(services);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
host.Run();
A partir de 2.0 se desaconseja cualquier acción en BuildWebHost
, excepto la compilación y la configuración del host web. Todo lo relacionado con la ejecución de la aplicación deberá gestionarse fuera de BuildWebHost
, normalmente en el método Main
de Program.cs
.
Revisión de la configuración de compilación de la vista de Razor
Un tiempo de inicio de aplicación más rápido y unos lotes publicados más pequeños son de la máxima importancia para el usuario. Por ello, la compilación de la vista de Razor está habilitada de forma predeterminada en ASP.NET Core 2.0.
Ya no es necesario establecer la propiedad MvcRazorCompileOnPublish
en true. A menos que se esté deshabilitando la compilación de la vista, se puede quitar la propiedad del archivo .csproj
.
Si el destino es .NET Framework, se debe hacer referencia de forma explícita al paquete NuGet Microsoft.AspNetCore.Mvc.Razor.ViewCompilation en el archivo .csproj
:
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" />
Características "light-up" de Application Insights como base
Es importante configurar sin esfuerzo la instrumentación de rendimiento de la aplicación. Ahora puede basarse en las nuevas características "light-up" de Application Insights disponibles en las herramientas de Visual Studio 2017.
Los proyectos de ASP.NET Core 1.1 creados en Visual Studio 2017 han agregado Application Insights de forma predeterminada. Si no usa el SDK de Application Insights directamente, fuera de Program.cs
y Startup.cs
, siga estos pasos:
Si el destino es .NET Core, elimine el siguiente nodo
<PackageReference />
del archivo.csproj
:<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
Si el destino es .NET Core, elimine la invocación del método de extensión
UseApplicationInsights
deProgram.cs
:public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .UseApplicationInsights() .Build(); host.Run(); }
Quite la llamada API del lado cliente de Application Insights de
_Layout.cshtml
. Comprende las dos líneas de código siguientes:@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet @Html.Raw(JavaScriptSnippet.FullScript)
Si usa el SDK de Application Insights directamente, siga haciéndolo. El metapaquete 2.0 incluye la versión más reciente de Application Insights, por lo que si se hace referencia a una versión anterior, aparece un error de degradación de paquete.
Mejoras de Identity y adopción de la autenticación
ASP.NET Core 2.0 tiene un nuevo modelo de autenticación y presenta una serie de cambios significativos en ASP.NET Core Identity. Si ha creado el proyecto con la opción Cuentas de usuario individuales habilitada, o bien si ha agregado manualmente la autenticación o Identity, vea Migración de la autenticación e Identity a ASP.NET Core 2.0.