Compartir a través de


Migración de ASP.NET Core 1.x a 2.0

Por Scott Addie

En este artículo, le guiaremos a través de la actualización de un proyecto de ASP.NET Core 1.x existente a ASP.NET Core 2.0. La migración de la aplicación a ASP.NET Core 2.0 le permite aprovechar muchas características nuevas y mejoras de rendimiento.

Las aplicaciones ASP.NET Core 1.x existentes se basan en plantillas de proyecto específicas de la versión. A medida que evoluciona el marco de ASP.NET Core, haga lo mismo con las plantillas de proyecto y el código de inicio que contiene. Además de actualizar el marco ASP.NET Core, debe actualizar el código de la aplicación.

Prerrequisitos

Consulte Introducción a ASP.NET Core.

Actualizar Indicador del marco de trabajo de destino (TFM)

Los proyectos destinados a .NET Core deben usar el TFM de una versión mayor o igual que .NET Core 2.0. Busque el <TargetFramework> nodo del .csproj archivo y reemplace su texto interno por netcoreapp2.0:

<TargetFramework>netcoreapp2.0</TargetFramework>

Los proyectos destinados a .NET Framework deben usar el TFM de una versión mayor o igual que .NET Framework 4.6.1. Busque el <TargetFramework> nodo del .csproj archivo 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 tiene como destino .NET Framework únicamente debido a las API que faltan en .NET Core 1.x, es probable que el destino sea .NET Core 2.0.

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 global.json archivo para tener como destino una versión específica del SDK de .NET Core, actualice su version propiedad para usar la versión 2.0 instalada en el equipo:

{
  "sdk": {
    "version": "2.0.0"
  }
}

Actualización de las referencias del paquete

El .csproj archivo de un proyecto 1.x enumera cada paquete NuGet usado por el proyecto.

En un proyecto de ASP.NET Core 2.0 destinado a .NET Core 2.0, una única referencia de metapaquete en el .csproj archivo reemplaza 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 se incluyen en el metapaquete.

Los proyectos de ASP.NET Core 2.0 destinados a .NET Framework deben continuar haciendo referencia a paquetes NuGet individuales. Actualice el Version atributo de cada <PackageReference /> nodo a 2.0.0.

Por ejemplo, esta es la lista de nodos usados en un proyecto típico de <PackageReference /> ASP.NET Core 2.0 destinado a .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. Todavía está disponible, pero no es compatible.

Actualización de las herramientas de la CLI de .NET

En el .csproj archivo, actualice el Version atributo de cada <DotNetCliToolReference /> nodo a 2.0.0.

Por ejemplo, esta es la lista de herramientas de la CLI que se usan en un proyecto típico de ASP.NET Core 2.0 destinado a .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>

Cambiar nombre de la propiedad Fallback de destino del paquete

El .csproj archivo de un proyecto 1.x usó un nodo y una PackageTargetFallback 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>

Actualizar el método Main en Program.cs

En los proyectos 1.x, el Main método de Program.cs tiene el siguiente 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 2.0, el Main método 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 es necesaria para que funcionen las características del producto, como las migraciones de Entity Framework (EF) Core . Por ejemplo, la ejecución Update-Database desde la ventana consola del Administrador de paquetes o dotnet ef database update desde la línea de comandos (en los proyectos convertidos a ASP.NET Core 2.0) genera el siguiente error:

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 1.x, la adición de proveedores de configuración a una aplicación se realizó a través del Startup constructor . Los pasos necesarios para crear una instancia de ConfigurationBuilder, cargar 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 la configuración de appsettings.json, así como cualquier archivo appsettings.{Environment}.json que cumpla con la propiedad IHostingEnvironment.EnvironmentName. La ubicación de estos archivos está en la misma ruta de acceso que Startup.cs.

En los proyectos 2.0, el código de configuración reutilizable inherente a los proyectos 1.x se ejecuta en segundo plano. Por ejemplo, las variables de entorno y la configuración de la aplicación se cargan al iniciarse. El código equivalente Startup.cs se reduce a la inicialización IConfiguration con la instancia insertada.

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

public IConfiguration Configuration { get; }

Para quitar los proveedores predeterminados agregados por WebHostBuilder.CreateDefaultBuilder, invoque el Clear método en la IConfigurationBuilder.Sources propiedad dentro de ConfigureAppConfiguration. Para volver a agregar proveedores, use el ConfigureAppConfiguration método 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 usada por el método en el CreateDefaultBuilder fragmento de código anterior se puede ver aquí.

Para más información, consulte Configuración en ASP.NET Core.

Movimiento del código de inicialización de la base de datos

En los proyectos de 1.x con EF Core 1.x, un comando como dotnet ef migrations add hace lo siguiente:

  1. Crea una instancia de Startup
  2. Invoca el método ConfigureServices para registrar todos los servicios con inyección de dependencias (incluidos los tipos DbContext)
  3. Realiza sus tareas necesarias

En los proyectos que usan la versión 2.0 de EF Core, se invoca Program.BuildWebHost para obtener servicios de la aplicación. A diferencia de 1.x, esto tiene el efecto secundario adicional de invocar Startup.Configure. Si la aplicación 1.x invocó el código de inicialización de la base de datos en su Configure método, pueden producirse problemas inesperados. Por ejemplo, si la base de datos aún no existe, el código de propagación se ejecuta antes de la ejecución del EF Core comando Migrations. Este problema hace que se produzca un error en un dotnet ef migrations list comando si la base de datos aún no existe.

Considere el siguiente código de inicialización 1.x en el Configure método 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 la versión 2.0, es una mala práctica hacer cualquier cosa en BuildWebHost excepto compilar y configurar el host web. Todo lo relacionado con ejecutar la aplicación debe controlarse fuera de BuildWebHost, normalmente en el método Main de Program.cs.

Revisar la configuración de compilación de vista Razor

El tiempo de inicio de la aplicación más rápido y los paquetes publicados más pequeños son de suma importancia para usted. Por estos motivos, Razor la compilación de vistas está habilitada de forma predeterminada en ASP.NET Core 2.0.

Ya no es necesario establecer la MvcRazorCompileOnPublish propiedad en true. A menos que deshabilite la compilación de vistas, es posible que la propiedad se quite del archivo .csproj.

Al establecer como objetivo .NET Framework, aún necesita referenciar explícitamente el paquete de NuGet Microsoft.AspNetCore.Mvc.Razor.ViewCompilation en su archivo .csproj.

<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" />

Confiar en las características de "iluminación" de Application Insights

Es importante configurar sin esfuerzo la instrumentación del rendimiento de la aplicación. Ahora puede confiar en las nuevas características "activadas" de Application Insights disponibles en las herramientas de Visual Studio 2017.

ASP.NET proyectos de Core 1.1 creados en Visual Studio 2017 agregaron Application Insights de forma predeterminada. Si no usa directamente el SDK de Application Insights, fuera de Program.cs y Startup.cs, siga estos pasos:

  1. Si el destino es .NET Core, quite el siguiente <PackageReference /> nodo del .csproj archivo:

    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    
  2. Si el destino es .NET Core, quite la UseApplicationInsights invocación del método de extensión de Program.cs:

    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();
    
        host.Run();
    }
    
  3. Quite la llamada API del lado cliente de Application Insights de _Layout.cshtml. Consta de las dos líneas de código siguientes:

    @inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
    @Html.Raw(JavaScriptSnippet.FullScript)
    

Si usa directamente el SDK de Application Insights, siga haciéndolo. El metapaquete 2.0 incluye la versión más reciente de Application Insights, por lo que aparece un error de degradación del paquete si hace referencia a una versión anterior.

Adoptar mejoras en la autenticaciónIdentity

ASP.NET Core 2.0 tiene un nuevo modelo de autenticación y varios cambios significativos en ASP.NET Core Identity. Si creó su proyecto con cuentas de usuario individuales habilitadas, o si ha agregado manualmente la autenticación o Identity, consulte Migre la autenticación y Identity a ASP.NET Core 2.0.

Recursos adicionales