Migrar do ASP.NET Core 2.0 para 2.1

De Rick Anderson

Confira Novidades no ASP.NET Core 2.1 para obter uma visão geral dos novos recursos no ASP.NET Core 2.1.

Este artigo:

  • Aborda os conceitos básicos da migração de um aplicativo ASP.NET Core 2.0 para a versão 2.1.
  • Fornece uma visão geral das alterações nos modelos de aplicativo Web ASP.NET Core.

Uma maneira rápida de obter uma visão geral das alterações na versão 2.1 é:

  • Crie um aplicativo Web ASP.NET Core 2.0 chamado WebApp1.
  • Confirme o WebApp1 em um sistema de controle do código-fonte.
  • Exclua o WebApp1 e crie um aplicativo Web ASP.NET Core 2.1 chamado WebApp1 no mesmo lugar.
  • Examine as alterações na versão 2.1.

Este artigo fornece uma visão geral sobre a migração para o ASP.NET Core 2.1. Ele não contém uma lista completa de todas as alterações necessárias para migrar para a versão 2.1. Alguns projetos podem exigir mais etapas dependendo das opções selecionadas quando o projeto foi criado e das modificações feitas no projeto.

Atualizar o arquivo de projeto para usar versões 2.1

Atualize o arquivo de projeto:

  • Altere a estrutura de destino para .NET Core 2.1 atualizando o arquivo de projeto para <TargetFramework>netcoreapp2.1</TargetFramework>.
  • Substitua a referência de pacote para Microsoft.AspNetCore.All por uma referência de pacote para Microsoft.AspNetCore.App. Talvez seja necessário adicionar dependências que foram removidas de Microsoft.AspNetCore.All. Para obter mais informações, consulte metapacote Microsoft.AspNetCore.All para ASP.NET Core 2.0 e metapacote Microsoft.AspNetCore.App para ASP.NET Core.
  • Remova o atributo "Version" na referência de pacote para Microsoft.AspNetCore.App. Os projetos que usam <Project Sdk="Microsoft.NET.Sdk.Web"> não precisam definir a versão. A versão é implícita pela estrutura de destino e selecionada para corresponder melhor à maneira como o ASP.NET Core 2.1 funciona. Para obter mais informações, consulte a seção Regras para projetos direcionados à estrutura compartilhada .
  • Para aplicativos direcionados ao .NET Framework, atualize cada referência de pacote para 2.1.
  • Remova referências aos elementos <DotNetCliToolReference> para os pacotes a seguir. Essas ferramentas são agrupadas por padrão na CLI do .NET Core e não precisam ser instaladas separadamente.
    • 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: você pode remover o elemento <DotNetCliToolReference> para Microsoft.VisualStudio.Web.CodeGeneration.Tools. Você pode substituir essa ferramenta por uma versão instalada globalmente executando dotnet tool install -g dotnet-aspnet-codegenerator.
  • Para a versão 2.1, uma Biblioteca de Classes Razor é a solução recomendada para distribuir arquivos Razor. Se o aplicativo usar exibições inseridas ou se depender da compilação de arquivos Razor em runtime, adicione <CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory> a um <PropertyGroup> no arquivo de projeto.

A marcação a seguir mostra o arquivo de projeto 2.0 gerado pelo modelo:

<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>

A marcação a seguir mostra o arquivo de projeto 2.1 gerado pelo modelo:

<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>

Regras para projetos direcionados à estrutura compartilhada

Uma estrutura compartilhada é um conjunto de assemblies (arquivos .dll) que não estão em pastas do aplicativo. A estrutura compartilhada deve ser instalada no computador para executar o aplicativo. Saiba mais em A estrutura compartilhada.

O ASP.NET Core 2.1 inclui as seguintes estruturas compartilhadas:

A versão especificada pela referência do pacote é a versão mínima necessária . Por exemplo, um projeto que referencia as versões 2.1.1 desses pacotes não será executado em um computador com apenas o runtime 2.1.0 instalado.

Problemas conhecidos para projetos direcionados a uma estrutura compartilhada:

  • O SDK do .NET Core 2.1.300 (incluído pela primeira vez no Visual Studio 15.6) definiu a versão implícita do Microsoft.AspNetCore.App como 2.1.0, o que causou conflitos com o Entity Framework Core 2.1.1. A solução recomendada é atualizar o SDK do .NET Core para 2.1.301 ou posterior. Para obter mais informações, consulte Pacotes que compartilham dependências com Microsoft.AspNetCore.App não podem referenciar versões de patch.

  • Todos os projetos que devem usar Microsoft.AspNetCore.All ou Microsoft.AspNetCore.App devem adicionar uma referência de pacote para o pacote no arquivo de projeto, mesmo que contenham uma referência de projeto a outro projeto usando Microsoft.AspNetCore.All ou Microsoft.AspNetCore.App.

    Exemplo:

    • MyApp tem uma referência de pacote a Microsoft.AspNetCore.App.
    • MyApp.Tests tem uma referência de projeto a MyApp.csproj.

    Adicione uma referência de pacote para Microsoft.AspNetCore.App a MyApp.Tests. Para obter mais informações, consulte Teste de integração é difícil de configurar e pode interromper a manutenção de estrutura compartilhada.

Atualizar para as imagens do Docker 2.1

No ASP.NET Core 2.1, as imagens do Docker migraram para o repositório GitHub dotnet/dotnet-docker. A tabela a seguir mostra as alterações na imagem e marcas do 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

Altere as linhas FROM no Dockerfile para usar os novos nomes e marcas de imagem na coluna 2.1 da tabela anterior. Para obter mais informações, consulte Migrando de repositórios do docker aspnetcore para dotnet.

Alterações em Main

As imagens a seguir mostram as alterações feitas no arquivo Program.cs gerado pelo modelo.

old version differences

A imagem anterior mostra a versão 2.0 com as exclusões em vermelho.

A imagem a seguir mostra o código da versão 2.1. O código em verde substituiu o da versão 2.0:

new version differences

O código a seguir mostra a versão 2.1 do 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>();
    }
}

O novo Main substitui a chamada para BuildWebHost por CreateWebHostBuilder. IWebHostBuilder foi adicionado para dar suporte a uma nova infraestrutura de teste de integração.

Alterações em Startup

O código a seguir mostra as alterações no código gerado pelo modelo do 2.1. Todas as alterações são um código recém-adicionado, exceto que UseBrowserLink foi removido:

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();
        }
    }
}

As alterações de código anteriores são detalhadas em:

Alterações no código de autenticação

O ASP.NET Core 2.1 fornece o ASP.NET Core Identity como uma Biblioteca de Classes Razor (RCL).

Atualmente, a interface do usuário Identity 2.1 padrão não fornece novos recursos significativos na versão 2.0. Substituir Identity pelo pacote RCL é opcional. As vantagens de substituir o código do Identity gerando pelo modelo pela versão RCL incluem:

  • Muitos arquivos são movidos para fora da árvore de origem.
  • Quaisquer correções de bug ou novos recursos do Identity estão incluídos no metapacote Microsoft.AspNetCore.App. Você obtém automaticamente o Identity atualizado quando o Microsoft.AspNetCore.App é atualizado.

Se você fez alterações não triviais no código do Identity gerado pelo modelo:

  • As vantagens anteriores provavelmente não justificam a conversão para a versão RCL.
  • Você pode manter seu código do ASP.NET Core 2.0 Identity, ele é totalmente compatível.

O Identity 2.1 expõe pontos de extremidade com a área Identity. Por exemplo, a tabela a seguir mostra exemplos de pontos de extremidade do Identity que mudam de 2.0 para 2.1:

URL 2.0 URL 2.1
/Account/Login /Identity/Account/Login
/Account/Logout /Identity/Account/Logout
/Account/Manage /Identity/Account/Manage

Os aplicativos que têm código usando Identity e substituem a interface do usuário Identity 2.0 pela Biblioteca Identity 2.1 precisam levar em conta as URLs Identity têm o segmento /Identity anexado. Uma maneira de lidar com os novos pontos de extremidade Identity é configurar redirecionamentos, por exemplo, de /Account/Login para /Identity/Account/Login.

Atualizar o Identity para a versão 2.1

As seguintes opções estão disponíveis para atualizar o Identity para 2.1.

  • Use o código da versão 2.0 da interface do usuário do Identity sem alterações. O uso do código 2.0 da interface do usuário do Identity é totalmente compatível. Essa é uma boa abordagem quando alterações significativas foram feitas no código do Identity gerado .
  • Exclua o código do Identity 2.0 existente e o Faça scaffolding do Identity em seu projeto. Seu projeto usará a Biblioteca de Classes Razor do ASP.NET CoreIdentity. Você pode gerar código e interface do usuário para qualquer um dos códigos de interface do usuário do Identity modificados. Aplique as alterações de código ao código da interface do usuário onde foi feito scaffolding recentemente.
  • Exclua o código do Identity 2.0 existente e faça scaffolding do Identity em seu projeto com a opção Substituir todos os arquivos.

Substituir a interface do usuário 2.0 do Identity pela Identity biblioteca de classes Razor 2.1

Esta seção descreve as etapas para substituir o código Identity gerado pelo modelo ASP.NET Core 2.0 pela Biblioteca de Classes Razor do ASP.NET CoreIdentity. As etapas a seguir são para um projeto dos Razor Pages , mas a abordagem para um projeto MVC é semelhante.

  • Verifique se o arquivo de projeto foi atualizado para usar versões 2.1
  • Exclua as seguintes pastas e todos os arquivos nelas:
    • Controladores
    • Pages/Account/
    • Extensões
  • Compile o projeto.
  • Faça scaffolding do Identity no projeto:
    • Selecione os projetos saindo do arquivo _Layout.cshtml.
    • Selecione o ícone + no lado direito da classe de contexto dados. Aceite o nome padrão.
    • Selecione Adicionar para criar uma nova classe de contexto de dados. A criação de um novo contexto de dados é necessária para o scaffolding. Você remove o novo contexto de dados na próxima seção.

Atualizar após fazer scaffolding do Identity

  • Exclua a classe derivada IdentityDbContext gerada pelo scaffolding do Identity na pasta Areas/Identity/Data/ .

  • Excluir Areas/Identity/IdentityHostingStartup.cs.

  • Atualize o arquivo _LoginPartial.cshtml:

    • Mova Pages/_LoginPartial.cshtml para Pages/Shared/_LoginPartial.cshtml.
    • Adicione asp-area="Identity" aos links de formulário e âncora.
    • Atualize o elemento <form /> para <form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/Index", new { area = "" })" method="post" id="logoutForm" class="navbar-right">.

    O código a seguir mostra o arquivo _LoginPartial.cshtml atualizado:

    @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>
    }
    

Atualize ConfigureServices com o seguinte 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>();
}

Alterações nos arquivos Razor de projetos dos Razor Pages

O arquivo de layout

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

  • Em Areas/Identity/Pages/_ViewStart.cshtml, altere Layout = "/Pages/_Layout.cshtml" para Layout = "/Pages/Shared/_Layout.cshtml".

  • O arquivo _Layout.cshtml tem as seguintes alterações:

    • <partial name="_CookieConsentPartial" /> foi adicionado. Para obter mais informações, veja Suporte RGPD no ASP.NET Core.
    • jQuery muda de 2.2.0 para 3.3.1.

_ValidationScriptsPartial.cshtml

  • Pages/_ValidationScriptsPartial.cshtml move para Pages/Shared/_ValidationScriptsPartial.cshtml.
  • jquery.validate/1.14.0 muda para jquery.validate/1.17.0.

Arquivos novos

Os seguintes arquivos são adicionados:

  • Privacy.cshtml
  • Privacy.cshtml.cs

Consulte Suporte GDPR no ASP.NET Core para obter informações sobre os arquivos anteriores.

Alterações nos arquivos Razor de projetos do MVC

O arquivo de layout

O arquivo Layout.cshtml tem as seguintes alterações:

  • <partial name="_CookieConsentPartial" /> foi adicionado.
  • jQuery muda de 2.2.0 para 3.3.1

_ValidationScriptsPartial.cshtml

jquery.validate/1.14.0 muda para jquery.validate/1.17.0

Novos arquivos e métodos de ação

As seguintes opções foram adicionadas:

  • Views/Home/Privacy.cshtml
  • O método de ação Privacy é adicionado ao controlador Home.

Consulte Suporte GDPR no ASP.NET Core para obter informações sobre os arquivos anteriores.

Alterações no arquivo launchSettings.json

Como aplicativo do ASP.NET Core agora usam HTTPS por padrão, o arquivo Properties/launchSettings.json foi alterado.

O JSON a seguir mostra o arquivo launchSettings.json gerado pelo modelo 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/"
    }
  }
}

O JSON a seguir mostra o arquivo launchSettings.json gerado pelo novo modelo 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 saber mais, confira Impor HTTPS no ASP.NET Core.

Alterações de quebra

Cabeçalho de intervalo FileResult

FileResult não processa mais o cabeçalho Accept-Ranges por padrão. Para habilitar o cabeçalho Accept-Ranges, defina EnableRangeProcessing como true.

ControllerBase.File e cabeçalho de intervalo PhysicalFile

Os seguintes métodos ControllerBase não processam mais o cabeçalho Accept-Ranges por padrão:

Para habilitar o cabeçalho Accept-Ranges, defina o parâmetro EnableRangeProcessing como true.

Módulo do ASP.NET Core (ANCM)

Se o Módulo do ASP.NET Core (ANCM) não foi um componente selecionado quando o Visual Studio foi instalado ou se uma versão anterior do ANCM foi instalada no sistema, baixe o Instalador de Pacote de Hospedagem do .NET Core (download direto) mais recente e execute o instalador. Para obter mais informações, consulte Hospedagem de pacote.

Alterações adicionais