Partilhar via


Migrar do ASP.NET Core 2.2 para o 3.0

Por Scott Addie e Rick Anderson

Este artigo explica como atualizar um projeto existente do ASP.NET Core 2.2 para o ASP.NET Core 3.0. Pode ser útil criar um novo projeto ASP.NET Core 3.0 para:

  • Compare com o código ASP.NET Core 2.2.
  • Copie as alterações relevantes para o seu projeto ASP.NET Core 3.0.

Pré-requisitos

Atualizar a versão do SDK do .NET Core em global.json

Se a sua solução depende de um arquivo global.json para direcionar uma versão específica do SDK do .NET Core, atualize a sua version propriedade para a versão 3.0 instalada na sua máquina.

{
  "sdk": {
    "version": "3.0.100"
  }
}

Atualizar o arquivo de projeto

Atualizar o Framework de Destino

ASP.NET Core 3.0 ou posterior só é executado no .NET Core. Defina o Target Framework Moniker (TFM) como netcoreapp3.0:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

Remover referências de pacotes obsoletos

Um grande número de pacotes NuGet não é produzido para o ASP.NET Core 3.0. Essas referências de pacote devem ser removidas do seu arquivo de projeto. Considere o seguinte arquivo de projeto para um aplicativo Web ASP.NET Core 2.2:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

O arquivo de projeto atualizado para o ASP.NET Core 3.0:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

O arquivo de projeto ASP.NET Core 3.0 atualizado:

  • No <PropertyGroup>:

    • Atualiza o TFM para netcoreapp3.0
    • Remove o elemento <AspNetCoreHostingModel>. Para obter mais informações, consulte Modelo de hospedagem em processo neste documento.
  • No <ItemGroup>:

    • Microsoft.AspNetCore.App é removido. Para obter mais informações, consulte Referência da estrutura neste documento.
    • Microsoft.AspNetCore.Razor.Design é removido e está na seguinte lista de pacotes que já não estão a ser produzidos.

Para ver a lista completa de pacotes que não são mais produzidos, selecione a seguinte lista de expansão:

Clique para expandir a lista de embalagens que já não estão a ser produzidas
  • Microsoft.AspNetCore
  • Microsoft.AspNetCore.All
  • Microsoft.AspNetCore.App
  • Microsoft.AspNetCore.Antifalsificação
  • Microsoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.Abstractions
  • Microsoft.AspNetCore.Authentication.Cookies
  • Microsoft.AspNetCore.Authentication.Core
  • Microsoft.AspNetCore.Authentication.OAuth
  • Microsoft.AspNetCore.Authorization.Policy
  • Microsoft.AspNetCore.CookiePolicy
  • Microsoft.AspNetCore.Cors
  • Microsoft.AspNetCore.Diagnostics
  • Microsoft.AspNetCore.Diagnostics.HealthChecks
  • Microsoft.AspNetCore.HostFiltering
  • Microsoft.AspNetCore.Hospedagem
  • Microsoft.AspNetCore.Hosting.Abstrações
  • Microsoft.AspNetCore.Hosting.Server.Abstrações
  • Microsoft.AspNetCore.Http
  • Microsoft.AspNetCore.Http.Abstrações
  • Microsoft.AspNetCore.Http.Connections
  • Microsoft.AspNetCore.Http.Extensions
  • Microsoft.AspNetCore.HttpSubstituições
  • Microsoft.AspNetCore.HttpsPolicy
  • Microsoft.AspNetCore.Identity
  • Microsoft.AspNetCore.Localization
  • Microsoft.AspNetCore.Localization.Routing
  • Microsoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.Mvc.Abstrações
  • Microsoft.AspNetCore.Mvc.Analyzers
  • Microsoft.AspNetCore.Mvc.ApiExplorer
  • Microsoft.AspNetCore.Mvc.Api.Analyzers
  • Microsoft.AspNetCore.Mvc.Core
  • Microsoft.AspNetCore.Mvc.Cors
  • Microsoft.AspNetCore.Mvc.DataAnotações
  • Microsoft.AspNetCore.Mvc.Formatters.Json
  • Microsoft.AspNetCore.Mvc.Formatters.Xml
  • Microsoft.AspNetCore.Mvc.Localization
  • Microsoft.AspNetCore.Mvc.Razor
  • Microsoft.AspNetCore.Mvc.Razor. ViewCompilation
  • Microsoft.AspNetCore.Mvc.RazorPages
  • Microsoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.ViewFeatures
  • Microsoft.AspNetCore.Razor
  • Microsoft.AspNetCore.Razor. Tempo de execução
  • Microsoft.AspNetCore.Razor. Desenho
  • Microsoft.AspNetCore.ResponseCaching
  • Microsoft.AspNetCore.ResponseCaching.Abstrações
  • Microsoft.AspNetCore.ResponseCompression
  • Microsoft.AspNetCore.Reescrever
  • Microsoft.AspNetCore.Routing
  • Microsoft.AspNetCore.Routing.Abstrações
  • Microsoft.AspNetCore.Server.HttpSys
  • Microsoft.AspNetCore.Server.IIS
  • Microsoft.AspNetCore.Server.IISIntegration
  • Microsoft.AspNetCore.Server.Kestrel
  • Microsoft.AspNetCore.Server.Kestrel. Núcleo
  • Microsoft.AspNetCore.Server.Kestrel. Disponível em:
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstrações
  • Microsoft.AspNetCore.Server.Kestrel. Transport.Sockets
  • Microsoft.AspNetCore.Session
  • Microsoft.AspNetCore.SignalR
  • Microsoft.AspNetCore.SignalR. Núcleo
  • Microsoft.AspNetCore.StaticFiles
  • Microsoft.AspNetCore.WebSockets
  • Microsoft.AspNetCore.WebUtilities
  • Microsoft.Net.Http.Headers

Rever as alterações que quebram

Rever as alterações de ruptura

Referência-quadro

Os recursos do ASP.NET Core que estavam disponíveis por meio de um dos pacotes listados acima estão disponíveis como parte da Microsoft.AspNetCore.App estrutura compartilhada. A estrutura compartilhada é o conjunto de assemblies (arquivos.dll ) instalados na máquina e inclui um componente de tempo de execução e um pacote de destino. Para obter mais informações, consulte A estrutura compartilhada.

  • Os projetos destinados ao Microsoft.NET.Sdk.Web SDK fazem referência implícita à Microsoft.AspNetCore.App estrutura.

    Não são necessárias referências adicionais para estes projetos:

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
        ...
    </Project>
    
  • Projetos que visem o SDK Microsoft.NET.Sdk ou Microsoft.NET.Sdk.Razor, devem adicionar explicitamente um FrameworkReference a Microsoft.AspNetCore.App:

    <Project Sdk="Microsoft.NET.Sdk.Razor">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
      </ItemGroup>
        ...
    </Project>
    

Compilações dependentes da estrutura usando o Docker

Compilações dependentes da estrutura de aplicativos de console que usam um pacote que depende da estrutura compartilhada ASP.NET Core podem fornecer o seguinte erro de tempo de execução:

It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '3.0.0' was not found.
  - No frameworks were found.

Microsoft.AspNetCore.App é a estrutura compartilhada que contém o tempo de execução do ASP.NET Core e só está presente na imagem do dotnet/core/aspnet Docker. O SDK 3.0 reduz o tamanho das compilações dependentes da estrutura usando o ASP.NET Core, não incluindo cópias duplicadas de bibliotecas que estão disponíveis na estrutura compartilhada. Esta é uma economia potencial de até 18 MB, mas requer que o tempo de execução do ASP.NET Core esteja presente/instalado para executar o aplicativo.

Para determinar se o aplicativo tem uma dependência (direta ou indireta) da estrutura compartilhada ASP.NET Core, examine o runtimeconfig.json arquivo gerado durante uma compilação/publicação do seu aplicativo. O seguinte arquivo JSON mostra uma dependência da estrutura compartilhada ASP.NET Core:

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "3.0.0"
    },
    "configProperties": {
      "System.GC.Server": true
    }
  }
}

Se seu aplicativo estiver usando o Docker, use uma imagem base que inclua ASP.NET Core 3.0. Por exemplo, docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0.

Adicionar referências de pacote para componentes removidos

ASP.NET Core 3.0 remove alguns assemblies que anteriormente faziam parte da Microsoft.AspNetCore.App referência do pacote. Para visualizar quais assemblies foram removidos, compare as duas pastas de estrutura compartilhadas. Por exemplo, uma comparação das versões 2.2.7 e 3.0.0:

Comparação de assemblies de estrutura compartilhada

Para continuar usando os recursos fornecidos pelos assemblies removidos, consulte as versões 3.0 dos pacotes correspondentes:

Alterações de inicialização

A imagem a seguir mostra as linhas excluídas e alteradas em um aplicativo Web do ASP.NET Core 2.2 Razor Pages:

as linhas excluídas e alteradas em um aplicativo Web ASP.NET Core 2.2 Razor

Na imagem anterior, o código excluído é mostrado em vermelho. O código excluído não mostra cookie o código de opções, que foi excluído antes de comparar os arquivos.

A imagem a seguir mostra as linhas adicionadas e alteradas em um aplicativo Web ASP.NET Core 3.0 Razor Pages:

as linhas adicionadas e alteradas em um aplicativo Web ASP.NET Core 3.0 Razor

Na imagem anterior, o código adicionado é mostrado em verde. Para obter informações sobre as seguintes alterações:

Suporte a analisadores

Projetos que têm como alvo Microsoft.NET.Sdk.Web referenciam implicitamente os analisadores anteriormente distribuídos como parte do pacote Microsoft.AspNetCore.Mvc.Analyzers. Não são necessárias referências adicionais para habilitá-los.

Se seu aplicativo usa analisadores de API enviados anteriormente usando o pacote Microsoft.AspNetCore.Mvc.Api.Analyzers , edite seu arquivo de projeto para fazer referência aos analisadores enviados como parte do SDK da Web do .NET Core:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
    </PropertyGroup>

    ...
</Project>

Razor Biblioteca de Classes

Razor os projetos de biblioteca de classes que fornecem componentes de interface do usuário para MVC devem definir a AddRazorSupportForMvc propriedade no arquivo de projeto:

<PropertyGroup>
  <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>

Modelo de hospedagem em processo

Os projetos utilizam por padrão o modelo de hospedagem em processo no ASP.NET Core 3.0 ou posterior. Opcionalmente, você pode remover a <AspNetCoreHostingModel> propriedade no arquivo de projeto se seu valor for InProcess.

Kestrel

Configuração

Migrar Kestrel a configuração para o construtor de host da Web fornecido por ConfigureWebHostDefaults (Program.cs):

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

Se o aplicativo criar o host manualmente com ConfigureWebHost em vez de ConfigureWebHostDefaults, chame UseKestrel no construtor de host da Web:

public static void Main(string[] args)
{
    var host = new HostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder.UseKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseIISIntegration()
            .UseStartup<Startup>();
        })
        .Build();

    host.Run();
}

O middleware de conexão substitui os adaptadores de conexão

Os adaptadores de conexão (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) foram removidos do Kestrel. Substitua adaptadores de conexão por middleware de conexão. O middleware de conexão é semelhante ao middleware HTTP no pipeline ASP.NET Core, mas para conexões de nível inferior. HTTPS e registro de conexão:

  • Foram movidos dos adaptadores de conectividade para o middleware de conectividade.
  • Esses métodos de extensão funcionam como nas versões anteriores do ASP.NET Core.

Para obter mais informações, consulte o exemplo TlsFilterConnectionHandler na seção ListenOptions.Protocols do Kestrel artigo.

Abstrações de transporte movidas e tornadas públicas

A Kestrel camada de transporte foi exposta como uma interface pública no Connections.Abstractions. Como parte dessas atualizações:

  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions e os tipos associados foram removidos.
  • NoDelay foi transferido de ListenOptions para as opções de transporte.
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode foi removido de KestrelServerOptions.

Para obter mais informações, consulte os seguintes recursos do GitHub:

Kestrel Solicitar cabeçalhos de rodapé

Para aplicativos destinados a versões anteriores do ASP.NET Core:

  • Kestrel adiciona cabeçalhos de trailer em partes HTTP/1.1 à coleção de cabeçalhos de solicitação.
  • Os trailers ficam disponíveis após a leitura do corpo do pedido até o final.

Isso causa algumas preocupações sobre a ambiguidade entre cabeçalhos e trailers, então os trailers foram movidos para uma nova coleção (RequestTrailerExtensions) em 3.0.

Os trailers de solicitação HTTP/2 são:

  • Não disponível no ASP.NET Core 2.2.
  • Disponível em 3.0 como RequestTrailerExtensions.

Novos métodos de extensão de solicitação estão presentes para acessar esses trailers. Tal como acontece com HTTP/1.1, os trailers estão disponíveis depois que o corpo da solicitação é lido até o final.

Para a versão 3.0, os seguintes RequestTrailerExtensions métodos estão disponíveis:

  • GetDeclaredTrailers: Obtém o cabeçalho da solicitação Trailer que lista quais trailers esperar após o corpo.
  • SupportsTrailers: Indica se a solicitação suporta o recebimento de cabeçalhos de trailer.
  • CheckTrailersAvailable: Verifica se a solicitação suporta trailers e se eles estão disponíveis para leitura. Esta verificação não pressupõe que haja trailers para ler. Pode não haver trailers para ler, mesmo que true seja retornado por esse método.
  • GetTrailer: Obtém o cabeçalho final solicitado da resposta. Verifique SupportsTrailers antes de chamar GetTrailer, ou pode ocorrer um NotSupportedException se a solicitação não suportar cabeçalhos finais.

Para obter mais informações, consulte Colocar trailers de solicitação em uma coleção separada (dotnet/AspNetCore #10410).

AllowSynchronousIO desativado

AllowSynchronousIO habilita ou desabilita APIs de E/S síncronas, como HttpRequest.Body.Read, HttpResponse.Body.Writee Stream.Flush. Essas APIs são uma fonte de saturação de threads que leva a crashes de aplicações. Na versão 3.0, AllowSynchronousIO está desativado por padrão. Para obter mais informações, consulte a seção E/S síncrona no Kestrel artigo.

Se a E/S síncrona for necessária, ela pode ser habilitada configurando a AllowSynchronousIO opção no servidor que está sendo usado (ao chamar ConfigureKestrel, por exemplo, se estiver usando Kestrel). Observe que os servidores (Kestrel, HttpSys, TestServer, etc.) têm sua própria AllowSynchronousIO opção que não afetará outros servidores. A E/S síncrona pode ser habilitada para todos os servidores por solicitação usando a IHttpBodyControlFeature.AllowSynchronousIO opção:

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();

if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

Se você tiver problemas com TextWriter implementações ou outros fluxos que chamam APIs síncronas em Dispose, chame a nova DisposeAsync API.

Para obter mais informações, consulte [Anúncio] AllowSynchronousIO desabilitado em todos os servidores (dotnet/AspNetCore #7644).

Buffer do formatador de saída

Newtonsoft.Json, XmlSerializer e DataContractSerializer os formatadores baseados na saída suportam apenas a serialização síncrona. Para permitir que esses formatters funcionem com as restrições AllowSynchronousIO do servidor, o MVC armazena em buffer a saída desses formatters antes de gravar no disco. Como resultado do armazenamento em buffer, o MVC incluirá o cabeçalho Content-Length ao responder usando esses formatadores.

System.Text.Json suporta serialização assíncrona e, consequentemente, o formatador baseado em System.Text.Json não armazena em buffer. Considere usar esse formatador para melhorar o desempenho.

Para desativar o buffer, os aplicativos podem configurar SuppressOutputFormatterBuffering em sua inicialização:

services.AddControllers(options => options.SuppressOutputFormatterBuffering = true)

Observe que isso pode resultar no aplicativo gerando uma exceção em tempo de execução se AllowSynchronousIO não estiver também configurado.

Microsoft.AspNetCore.Server.Kestrel. Assemblagem Https removida

No ASP.NET Core 2.1, o conteúdo de Microsoft.AspNetCore.Server.Kestrel.Https.dll foram movidos para Microsoft.AspNetCore.Server.Kestrel.Core.dll. Esta foi uma atualização ininterrupta usando TypeForwardedTo atributos. Para 3.0, o Microsoft.AspNetCore.Server.Kestrel.Https.dll assembly vazio e o pacote NuGet foram removidos.

Bibliotecas que fazem referência a Microsoft.AspNetCore.Server.Kestrel.Https devem atualizar as dependências do ASP.NET Core para 2.1 ou posterior.

Os aplicativos e bibliotecas destinados ao ASP.NET Core 2.1 ou posterior devem remover quaisquer referências diretas ao Microsoft.AspNetCore.Server.Kestrel Pacote Https .

Suporte Newtonsoft.Json (Json.NET)

Como parte do trabalho para melhorar a estrutura compartilhada ASP.NET Core, Newtonsoft.Json (Json.NET) foi removido da estrutura compartilhada ASP.NET Core.

O serializador JSON padrão para ASP.NET Core agora é System.Text.Json, que é novo no .NET Core 3.0. Considere usar System.Text.Json quando possível. É de alto desempenho e não requer uma dependência de biblioteca adicional. No entanto, como System.Text.Json é novo, pode estar faltando recursos que seu aplicativo precisa. Para obter mais informações, consulte Como migrar de Newtonsoft.Json para System.Text.Json.

Usar Newtonsoft.Json em um projeto ASP.NET Core 3.0 SignalR

  • Instale o Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson pacote NuGet.

  • No cliente, encadeie uma AddNewtonsoftJsonProtocol chamada de método para a HubConnectionBuilder instância:

    new HubConnectionBuilder()
        .WithUrl("/chathub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  • No servidor, encadeie uma chamada de método AddNewtonsoftJsonProtocol para a chamada de método AddSignalR em Startup.ConfigureServices:

    services.AddSignalR()
        .AddNewtonsoftJsonProtocol(...);
    

Use Newtonsoft.Json em um projeto ASP.NET Core 3.0 MVC

  • Instale o pacote Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  • Atualizar Startup.ConfigureServices para chamar AddNewtonsoftJson.

    services.AddMvc()
        .AddNewtonsoftJson();
    

    AddNewtonsoftJson é compatível com os novos métodos de registro de serviço MVC:

    • AddRazorPages
    • AddControllersWithViews
    • AddControllers
    services.AddControllers()
        .AddNewtonsoftJson();
    

    Newtonsoft.Json As configurações podem ser definidas na chamada para AddNewtonsoftJson:

    services.AddMvc()
        .AddNewtonsoftJson(options =>
               options.SerializerSettings.ContractResolver =
                  new CamelCasePropertyNamesContractResolver());
    

    Observação: Se o AddNewtonsoftJson método não estiver disponível, certifique-se de que instalou o Microsoft.AspNetCore.Mvc.NewtonsoftJson pacote. Um erro comum é instalar o pacote Newtonsoft.Json em vez do Microsoft.AspNetCore.Mvc.NewtonsoftJson pacote.

Para obter mais informações, consulte Adicionar suporte ao formato JSON baseado em Newtonsoft.Json.

Registro do serviço MVC

ASP.NET Core 3.0 adiciona novas opções para registrar cenários MVC dentro do Startup.ConfigureServices.

Três novos métodos de extensão de nível superior relacionados em cenários MVC estão disponíveis em IServiceCollection. Os modelos usam esses novos métodos em vez de AddMvc. No entanto, AddMvc continua a se comportar como em versões anteriores.

O exemplo a seguir adiciona suporte para controladores e recursos relacionados à API, mas não modos de exibição ou páginas. O modelo de API usa este código:

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

O exemplo a seguir adiciona suporte para controladores, recursos relacionados à API e modos de exibição, mas não páginas. O modelo de aplicativo Web (MVC) usa este código:

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

O exemplo a seguir adiciona suporte para Razor Pages e suporte mínimo ao controlador. O modelo de Aplicativo Web usa este código:

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

Os novos métodos também podem ser combinados. O exemplo a seguir é equivalente a chamar AddMvc no ASP.NET Core 2.2:

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

Código de inicialização de roteamento

Se uma aplicação chamar UseMvc ou UseSignalR, migre a aplicação para o Roteamento de Ponto de Extremidade, se possível. Para melhorar a compatibilidade do Endpoint Routing com versões anteriores do MVC, revertemos algumas das alterações na geração de URL introduzidas no ASP.NET Core 2.2. Se você teve problemas ao usar o Endpoint Routing na versão 2.2, espere melhorias no ASP.NET Core 3.0 com as seguintes exceções:

  • Se a aplicação implementar IRouter ou herdar do Route, use DynamicRouteValuesTransformer como substituto.
  • Se o aplicativo acessar RouteData.Routers diretamente dentro do MVC para analisar URLs, você poderá substituí-lo pelo uso de LinkParser.ParsePathByEndpointName.
    • Defina a rota com um nome de rota.
    • Use LinkParser.ParsePathByEndpointName e passe o nome da rota desejada.

O Roteamento de Pontos de Extremidade suporta a mesma sintaxe de padrão de rota e os mesmos recursos de criação de padrões de rota que IRouter. O Endpoint Routing suporta IRouteConstraint. O roteamento de ponto de extremidade suporta [Route], [HttpGet]e os outros atributos de roteamento MVC.

Para a maioria das aplicações, apenas Startup requer alterações.

Migrar inicialização.Configurar

Conselhos gerais:

  • Adicionar UseRouting.

  • Se o app chamar UseStaticFiles, coloque UseStaticFilesantesUseRouting.

  • Caso o aplicativo utilize recursos de autenticação/autorização, como AuthorizePage ou [Authorize], faça a chamada para UseAuthentication e UseAuthorization: depois, UseRouting e UseCors, mas antes de UseEndpoints:

    public void Configure(IApplicationBuilder app)
    {
      ...
    
      app.UseStaticFiles();
    
      app.UseRouting();
      app.UseCors();
    
      app.UseAuthentication();
      app.UseAuthorization();
    
      app.UseEndpoints(endpoints => {
         endpoints.MapControllers();
      });
    
  • Substitua UseMvc ou UseSignalR por UseEndpoints.

  • Se o aplicativo usar cenários de CORS , como [EnableCors], coloque a chamada para UseCors antes de qualquer outro middleware que use CORS (por exemplo, coloque UseCors antes de UseAuthentication, UseAuthorizatione UseEndpoints).

  • Substitua IHostingEnvironment por IWebHostEnvironment e adicione uma instrução using para o namespace Microsoft.AspNetCore.Hosting.

  • Substitua IApplicationLifetime por IHostApplicationLifetime (Microsoft.Extensions.Hosting namespace).

  • Substitua EnvironmentName por Environments (Microsoft.Extensions.Hosting namespace).

O código a seguir é um exemplo de Startup.Configure em um aplicativo ASP.NET Core 2.2 típico:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseSignalR(hubs =>
    {
        hubs.MapHub<ChatHub>("/chat");
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

Após atualizar o código anterior Startup.Configure :

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseRouting();

    app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chat");
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

Advertência

Para a maioria dos aplicativos, as chamadas para UseAuthentication, UseAuthorizatione UseCors devem aparecer entre as chamadas para UseRouting e UseEndpoints para serem eficazes.

Verificações de Saúde

As Verificações de Integridade usam o roteamento de ponto de extremidade com o Host Genérico. No Startup.Configure, chame MapHealthChecks o construtor de pontos de extremidade com a URL do ponto de extremidade ou o caminho relativo:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

Os Endpoints das Verificações de Integridade podem:

  • Especifique um ou mais hosts/portas permitidos.
  • Requer autorização.
  • Exigir CORS.

Para obter mais informações, consulte verificações de integridade no ASP.NET Core.

Diretrizes de middleware de segurança

O suporte para autorização e CORS é unificado na abordagem de middleware. Isso permite o uso do mesmo middleware e funcionalidade nesses cenários. Um middleware de autorização atualizado é fornecido nesta versão, e o CORS Middleware é aprimorado para que possa entender os atributos usados pelos controladores MVC.

CORS

Anteriormente, o CORS podia ser difícil de configurar. O middleware foi fornecido para uso em alguns casos de uso, mas os filtros MVC foram projetados para serem usados sem o middleware em outros casos de uso. Com o ASP.NET Core 3.0, recomendamos que todos os aplicativos que exigem CORS usem o middleware CORS em conjunto com o roteamento de endpoint. UseCors pode ser fornecido com uma política padrão, e os atributos [EnableCors] e [DisableCors] podem ser usados para substituir a política padrão quando necessário.

No exemplo a seguir:

  • O CORS está ativado para todos os endpoints com a política denominada default.
  • A MyController classe desativa CORS com o [DisableCors] atributo.
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseCors("default");

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

[DisableCors]
public class MyController : ControllerBase
{
    ...
}

Autorização

Em versões anteriores do ASP.NET Core, o suporte à autorização era fornecido por meio do [Authorize] atributo. O middleware de autorização não estava disponível. No ASP.NET Core 3.0, o middleware de autorização é necessário. Recomendamos colocar o ASP.NET Core Authorization Middleware (UseAuthorization) imediatamente após UseAuthentication. O middleware de autorização também pode ser configurado com uma política padrão, que pode ser substituída.

No ASP.NET Core 3.0 ou posterior, UseAuthorization é chamado em Startup.Configure, e o seguinte HomeController requer um utilizador com sessão iniciada:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

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

public class HomeController : Controller
{
    [Authorize]
    public IActionResult BuyWidgets()
    {
        ...
    }
}

Ao usar o roteamento de ponto final, recomendamos não configurar AuthorizeFilter e, em vez disso, confiar no middleware de autorização. Se o aplicativo usar um AuthorizeFilter como um filtro global no MVC, recomendamos refatorar o código para fornecer uma política na chamada para AddAuthorization.

O DefaultPolicy é inicialmente configurado para exigir autenticação, portanto, nenhuma configuração adicional é necessária. No exemplo a seguir, os pontos de extremidade MVC são marcados como RequireAuthorization de modo que todas as solicitações devem ser autorizadas com base no DefaultPolicy. No entanto, o HomeController permite acesso sem que o utilizador inicie sessão na aplicação devido a [AllowAnonymous].

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute().RequireAuthorization();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

Autorização para parâmetros de avaliação específicos

A autorização também pode ser configurada para classes específicas de endpoints. O código a seguir é um exemplo de conversão de um aplicativo MVC que configurou um global AuthorizeFilter em um aplicativo com uma política específica que requer autorização:

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

    static readonly string _RequireAuthenticatedUserPolicy = 
                            "RequireAuthenticatedUserPolicy";
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        // Pre 3.0:
        // services.AddMvc(options => options.Filters.Add(new AuthorizeFilter(...));

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
                        builder => builder.RequireAuthenticatedUser()));

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

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

As políticas também podem ser personalizadas. O DefaultPolicy está configurado para exigir autenticação:

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
              .RequireAuthenticatedUser()
              .Build();
        });

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute().RequireAuthorization();
            endpoints.MapRazorPages();
        });
    }
}
[AllowAnonymous]
public class HomeController : Controller
{

Como alternativa, todos os pontos de extremidade podem ser configurados para exigir autorização sem [Authorize] ou RequireAuthorization ao configurar um FallbackPolicy. O FallbackPolicy é diferente do DefaultPolicy. O DefaultPolicy é acionado por [Authorize] ou RequireAuthorization, enquanto o FallbackPolicy é acionado quando nenhuma outra política é definida. FallbackPolicy é inicialmente configurado para permitir solicitações sem autorização.

O exemplo a seguir é o mesmo que o exemplo anterior DefaultPolicy, mas usa o FallbackPolicy para requerer sempre autenticação em todos os pontos de extremidade, exceto quando [AllowAnonymous] é especificado.

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
    });
}

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

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

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

A autorização por middleware funciona sem que o framework tenha qualquer conhecimento específico de autorização. Por exemplo, as verificações de integridade não têm conhecimento específico de autorização, mas as verificações de integridade podem ter uma política de autorização configurável aplicada pelo middleware.

Além disso, cada ponto de extremidade pode personalizar seus requisitos de autorização. No exemplo a seguir, UseAuthorization processa autorização com DefaultPolicy, mas o endpoint de verificação de saúde /healthz requer um utilizador admin.

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints
            .MapHealthChecks("/healthz")
            .RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", });
    });
}

A proteção é implementada para alguns cenários. Pontos de extremidade O middleware lança uma exceção se uma política de autorização ou CORS for ignorada devido à falta de middleware. O suporte ao analisador para fornecer feedback adicional sobre erros de configuração está em andamento.

Manipuladores de autorização personalizados

Se a aplicação utilizar manipuladores de autorização personalizados, o roteamento de ponto de extremidade passa um tipo de recurso diferente para os manipuladores do que o MVC. Os manipuladores que esperam que o recurso de contexto do manipulador de autorização seja do tipo AuthorizationFilterContext (o tipo de recurso fornecido pelos filtros MVC) precisarão ser atualizados para lidar com recursos do tipo RouteEndpoint (o tipo de recurso dado aos manipuladores de autorização pelo roteamento de ponto de extremidade).

O MVC ainda usa AuthorizationFilterContext recursos, portanto, se o aplicativo usar filtros de autorização MVC junto com a autorização de roteamento de ponto final, pode ser necessário lidar com ambos os tipos de recursos.

SignalR

O mapeamento dos SignalR agora ocorre dentro de UseEndpoints.

Mapeie cada hub com MapHub. Como nas versões anteriores, cada hub é explicitamente listado.

No exemplo a seguir, o suporte para o ChatHubSignalR hub é adicionado:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>();
    });
}

Há uma nova opção para controlar os limites de tamanho de mensagem dos clientes. Por exemplo, em Startup.ConfigureServices:

services.AddSignalR(hubOptions =>
{
    hubOptions.MaximumReceiveMessageSize = 32768;
});

No ASP.NET Core 2.2, você pode definir o TransportMaxBufferSize e que controlaria efetivamente o tamanho máximo da mensagem. No ASP.NET Core 3.0, essa opção agora controla apenas o tamanho máximo antes que a contrapressão seja observada.

SignalR Assemblies em estrutura compartilhada

As assemblies do lado do servidor do ASP.NET Core SignalR agora são instaladas com o SDK do .NET Core. Para obter mais informações, consulte Remover referências de pacotes obsoletos neste documento.

Controladores MVC

O mapeamento dos controladores agora ocorre dentro do UseEndpoints.

Adicione MapControllers se o aplicativo usa roteamento de atributos. Como o roteamento inclui suporte para muitas estruturas no ASP.NET Core 3.0 ou posterior, a adição de controladores roteados por atributos é opcional.

Substitua o seguinte:

  • MapRoute com MapControllerRoute
  • MapAreaRoute com MapAreaControllerRoute

Como o roteamento agora inclui suporte para mais do que apenas MVC, a terminologia mudou para fazer com que esses métodos indiquem claramente o que fazem. Rotas convencionais como MapControllerRoute/MapAreaControllerRoute/MapDefaultControllerRoute são aplicadas na ordem em que são adicionadas. Coloque rotas mais específicas (como rotas para uma área) primeiro.

No exemplo a seguir:

  • MapControllers Adiciona suporte para controladores roteados por atributos.
  • MapAreaControllerRoute adiciona uma rota convencional para controladores numa determinada área.
  • MapControllerRoute adiciona uma rota convencional para controladores.
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapAreaControllerRoute(
            "admin",
            "admin",
            "Admin/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapControllerRoute(
            "default", "{controller=Home}/{action=Index}/{id?}");
    });
}

Remoção do sufixo 'Async' dos nomes de ação do controlador

No ASP.NET Core 3.0, ASP.NET Core MVC remove o sufixo Async dos nomes de ação do controlador. Tanto o roteamento quanto a geração de links são afetados por esse novo padrão. Por exemplo:

public class ProductsController : Controller
{
    public async Task<IActionResult> ListAsync()
    {
        var model = await _dbContext.Products.ToListAsync();
        return View(model);
    }
}

Antes do ASP.NET Core 3.0:

  • A ação anterior pode ser acessada na rota Products/ListAsync .

  • A geração de links exigia a especificação do sufixo Async . Por exemplo:

    <a asp-controller="Products" asp-action="ListAsync">List</a>
    

Em ASP.NET Core 3.0:

  • A ação anterior pode ser acessada na rota Produtos/Lista .

  • A geração de links não requer a especificação do sufixo Async . Por exemplo:

    <a asp-controller="Products" asp-action="List">List</a>
    

Essa alteração não afeta os nomes especificados usando o [ActionName] atributo. O comportamento padrão pode ser desativado com o seguinte código em Startup.ConfigureServices:

services.AddMvc(options =>
    options.SuppressAsyncSuffixInActionNames = false);

Existem algumas diferenças na geração de links (usando o Url.Link e APIs semelhantes, por exemplo). Estes são, entre outros:

  • Por padrão, ao usar o roteamento de ponto final, o invólucro de parâmetros de rota em URIs gerados não é necessariamente preservado. Esse comportamento pode ser controlado com a IOutboundParameterTransformer interface.
  • A geração de um URI para uma rota inválida (um controlador/ação ou página que não existe) produzirá uma cadeia de caracteres vazia no roteamento de ponto final em vez de produzir um URI inválido.
  • Os valores de ambiente (parâmetros de rota do contexto atual) não são usados automaticamente na geração de links com roteamento de pontos finais. Anteriormente, ao gerar um link para outra ação (ou página), valores de rota não especificados seriam inferidos a partir dos valores ambientais de rotas atuais . Ao usar o roteamento de ponto final, todos os parâmetros de rota devem ser especificados explicitamente durante a geração do link.

Razor Páginas

O mapeamento Razor de páginas agora ocorre dentro do UseEndpoints.

Adicione MapRazorPages se o aplicativo usa Razor Páginas. Como o Endpoint Routing inclui suporte para muitas estruturas, a adição de Razor Pages agora é opcional.

No método Startup.Configure a seguir, MapRazorPages adiciona suporte para Razor Pages:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

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

Usar MVC sem roteamento de endpoints

Usar MVC via UseMvc ou UseMvcWithDefaultRoute no ASP.NET Core 3.0 requer uma ativação explícita dentro de Startup.ConfigureServices. Isso é necessário porque o MVC deve saber se pode confiar na autorização e no middleware CORS durante a inicialização. É fornecido um analisador que avisa se o aplicativo tenta usar uma configuração sem suporte.

Se a aplicação exigir suporte herdado IRouter, desative EnableEndpointRouting através de uma das seguintes abordagens em Startup.ConfigureServices:

services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddControllers(options => options.EnableEndpointRouting = false);
services.AddControllersWithViews(options => options.EnableEndpointRouting = false);
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);

Controlos sanitários

As verificações de integridade podem ser usadas como um software de roteador com o Roteamento de Endpoint.

Adicione MapHealthChecks para utilizar verificações de integridade com o Endpoint Routing. O MapHealthChecks método aceita argumentos semelhantes a UseHealthChecks. A vantagem de usar MapHealthChecks em relação a UseHealthChecks é a capacidade de aplicar autorização e ter um controle mais refinado sobre a política de correspondência.

No exemplo a seguir, MapHealthChecks é chamado para um ponto de verificação de saúde em /healthz:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthz", new HealthCheckOptions() { });
    });
}

HostBuilder substitui WebHostBuilder

Os modelos do ASP.NET Core 3.0 usam o Host Genérico. As versões anteriores usavam Web Host. O código a seguir mostra a classe gerada Program pelo modelo ASP.NET Core 3.0:

// requires using Microsoft.AspNetCore.Hosting;
// requires using Microsoft.Extensions.Hosting;

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

O código a seguir mostra a classe gerada por modelo Program do ASP.NET Core 2.2:

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

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

IWebHostBuilder permanece na versão 3.0 e é o tipo usado no exemplo de código apresentado anteriormente no webBuilder. WebHostBuilder será preterido em uma versão futura e substituído por HostBuilder.

A mudança mais significativa de WebHostBuilder para HostBuilder é na injeção de dependência (DI). Ao usar HostBuilder, você só pode injetar o seguinte no construtor de Startup:

As HostBuilder restrições de DI:

  • Habilite o contêiner DI para ser construído apenas uma vez.
  • Evita problemas do ciclo de vida do objeto, como resolver múltiplas instâncias de singletons.

Para obter mais informações, consulte Evitando a injeção do serviço de inicialização no ASP.NET Core 3.

AddAuthorization movido para um assembly diferente

O ASP.NET Core 2.2 e métodos inferiores AddAuthorization em Microsoft.AspNetCore.Authorization.dll:

  • Foram renomeados AddAuthorizationCore.
  • Mudaram para Microsoft.AspNetCore.Authorization.Policy.dll.

Os aplicativos que usam Microsoft.AspNetCore.Authorization.dll e Microsoft.AspNetCore.Authorization.Policy.dll não são afetados.

Os aplicativos que não estão usando Microsoft.AspNetCore.Authorization.Policy.dll devem seguir um destes procedimentos:

  • Adicione uma referência a Microsoft.AspNetCore.Authorization.Policy.dll. Essa abordagem funciona para a maioria dos aplicativos e é tudo o que é necessário.
  • Mudar para a utilização de AddAuthorizationCore

Para obter mais informações, consulte Alteração significativa na sobrecarga AddAuthorization(o => está em um assembly diferente #386.

Identity Interface do usuário

Identity Atualizações da interface do usuário para o ASP.NET Core 3.0:

  • Adicione uma referência de pacote a Microsoft.AspNetCore.Identity. UI.
  • Apps que não utilizam Razor Páginas devem chamar MapRazorPages. Consulte Razor Páginas neste documento.
  • O Bootstrap 4 é a estrutura padrão da interface do usuário. Defina uma IdentityUIFrameworkVersion propriedade de projeto para alterar o padrão. Para obter mais informações, consulte este anúncio do GitHub.

SignalR

O SignalR cliente JavaScript foi alterado de @aspnet/signalr para @microsoft/signalr. Para reagir a essa alteração, altere as referências em package.json arquivos, require instruções e instruções ECMAScript import .

System.Text.Json é o protocolo padrão

System.Text.Json agora é o protocolo Hub padrão usado pelo cliente e pelo servidor.

No Startup.ConfigureServices, chame AddJsonProtocol para definir opções do serializador.

Servidor:

services.AddSignalR(...)
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.WriteIndented = false;
        })

Cliente:

new HubConnectionBuilder()
    .WithUrl("/chathub")
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.WriteIndented = false;
    })
    .Build();

Troque para Newtonsoft.Json

Se você estiver usando recursos do Newtonsoft.Json que não são suportados em System.Text.Json, você pode voltar para Newtonsoft.Json. Consulte Usar Newtonsoft.Json em um projeto ASP.NET Core 3.0 SignalR anteriormente neste artigo.

Caches distribuídos Redis

O pacote Microsoft.Extensions.Caching.Redis não está disponível para aplicativos ASP.NET Core 3.0 ou posteriores. Substitua a referência do pacote por Microsoft.Extensions.Caching.StackExchangeRedis. Para obter mais informações, consulte Cache distribuído no ASP.NET Core.

Optar pela compilação em tempo de execução

Antes do ASP.NET Core 3.0, a compilação de visualizações em tempo de execução era um recurso implícito da estrutura. A compilação em tempo de execução complementa a compilação de visualizações em tempo de compilação. Ele permite que a estrutura compile Razor visualizações e páginas (.cshtml arquivos) quando os arquivos são modificados, sem ter que reconstruir todo o aplicativo. Esse recurso suporta o cenário de fazer uma edição rápida no IDE e atualizar o navegador para visualizar as alterações.

No ASP.NET Core 3.0, a compilação em tempo de execução é um cenário opcional. A compilação em tempo de construção é o único mecanismo para compilação de visualização habilitado por padrão. O tempo de execução depende do Visual Studio ou dotnet-watch no Visual Studio Code para reconstruir o projeto quando deteta alterações em .cshtml ficheiros. No Visual Studio, as alterações nos .cs, .cshtml, ou .razor ficheiros no projeto em execução (Ctrl+F5), mas sem depuração (F5), acionam a recompilação do projeto.

Para habilitar a compilação em tempo de execução em seu projeto ASP.NET Core 3.0:

  1. Instale o pacote NuGet Razor.

  2. Atualizar Startup.ConfigureServices para chamar AddRazorRuntimeCompilation:

    Para ASP.NET MVC principal, use o seguinte código:

    services.AddControllersWithViews()
        .AddRazorRuntimeCompilation(...);
    

    Para ASP.NET Core Razor Pages, use o seguinte código:

    services.AddRazorPages()
        .AddRazorRuntimeCompilation(...);
    

A amostra em https://github.com/aspnet/samples/tree/main/samples/aspnetcore/mvc/runtimecompilation mostra um exemplo de habilitar condicionalmente a compilação em tempo de execução em ambientes Development.

Para obter mais informações sobre Razor a compilação de arquivos, consulte Razor Compilação de arquivos no ASP.NET Core.

Migrar bibliotecas por meio de multisegmentação

As bibliotecas geralmente precisam oferecer suporte a várias versões do ASP.NET Core. A maioria das bibliotecas que foram compiladas em relação às versões anteriores do ASP.NET Core deve continuar funcionando sem problemas. As seguintes condições exigem que o aplicativo seja compilado de forma cruzada:

  • A biblioteca depende de um recurso que tem uma alteração de quebra binária.
  • A biblioteca quer aproveitar os novos recursos do ASP.NET Core 3.0.

Por exemplo:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
  </ItemGroup>
</Project>

Use #ifdefs para habilitar APIs específicas do ASP.NET Core 3.0:

var webRootFileProvider =
#if NETCOREAPP3_0
    GetRequiredService<IWebHostEnvironment>().WebRootFileProvider;
#elif NETSTANDARD2_0
    GetRequiredService<IHostingEnvironment>().WebRootFileProvider;
#else
#error unknown target framework
#endif

Para obter mais informações sobre como usar APIs ASP.NET Core em uma biblioteca de classes, consulte Usar APIs ASP.NET Core em uma biblioteca de classes.

Alterações diversas

O sistema de validação no .NET Core 3.0 ou posterior trata parâmetros não anuláveis ou propriedades acopladas como se tivessem um [Required] atributo. Para obter mais informações, consulte [Obrigatório] atributo.

Publicar

Exclua as pastas bin e obj no diretório do projeto.

Servidor de Testes

Para aplicações que usam TestServer diretamente com o Host Genérico, crie o TestServer em IWebHostBuilder em ConfigureWebHost:

[Fact]
public async Task GenericCreateAndStartHost_GetTestServer()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .Configure(app => { });
        })
    .StartAsync();

    var response = await host.GetTestServer().CreateClient().GetAsync("/");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

Alterações de grande impacto

Use os artigos em Alterações significativas no .NET para encontrar alterações significativas que podem ser aplicadas ao atualizar um aplicativo para uma versão mais recente do .NET.

Para obter mais informações, consulte os seguintes recursos:

Roteamento de endpoint com parâmetro abrangente

Advertência

Um parâmetro catch-all pode corresponder a rotas incorretamente devido a um erro no roteamento. Os aplicativos afetados por esse bug têm as seguintes características:

  • Uma rota abrangente, por exemplo, {**slug}"
  • A rota de abrangência total não processa as solicitações que deveria processar.
  • A remoção de outras rotas faz com que a rota "catch-all" passe a funcionar.

Veja os bugs 18677 e 16579 do GitHub, por exemplo, casos que atingiram esse bug.

Uma correção opcional para esse bug está contida no SDK do .NET Core 3.1.301 ou posterior. O código a seguir define uma opção interna que corrige esse bug:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

.NET Core 3.0 no Serviço de Aplicativo do Azure

A implantação do .NET Core para o Serviço de Aplicativo do Azure foi concluída. O .NET Core 3.0 está disponível em todos os datacenters do Serviço de Aplicativo do Azure.

Módulo ASP.NET Core (ANCM)

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