Novidades do ASP.NET Core 3.0

Este artigo destaca as alterações mais significativas no ASP.NET Core 3.0, com links para a documentação relevante.

Blazor

Blazor é uma nova estrutura no ASP.NET Core para criar uma interface do usuário da Web interativa do lado do cliente com o .NET:

  • Crie UIs interativas avançadas usando C#.
  • Compartilhe a lógica de aplicativo do lado do cliente e do servidor gravada no .NET.
  • Renderize a interface do usuário, como HTML e CSS para suporte amplo de navegadores, incluindo navegadores móveis.

Cenários compatíveis com a estrutura Blazor:

  • Componentes da interface do usuário reutilizáveis (componentes Razor)
  • Roteamento do lado do cliente
  • Layouts do componente
  • Suporte para injeção de dependência
  • Formulários e validação
  • Fornecer componentes Razor em bibliotecas de classes Razor
  • Interoperabilidade do JavaScript

Para obter mais informações, confira Blazor ASP.NET Core.

Blazor Server

O Blazor desvincula a lógica de renderização do componente da forma como as atualizações da interface do usuário são aplicadas. O Blazor Server dá suporte para hospedar os componentes do Razor no servidor em um aplicativo ASP.NET Core. As atualizações da interface do usuário são tratadas por uma conexão SignalR. Há suporte para Blazor Server no ASP.NET Core 3.0.

Blazor WebAssembly (versão prévia)

Os aplicativos Blazor também podem ser executados diretamente no navegador usando um runtime do .NET baseado em WebAssembly. Blazor WebAssembly está em versão prévia e não é compatível com o ASP.NET Core 3.0. Haverá suporte para Blazor WebAssembly em uma versão futura do ASP.NET Core.

Componentes Razor

Os aplicativos Blazor são criados a partir dos componentes. Os componentes são partes autônomas da interface do usuário, como uma página, caixa de diálogo ou formulário. Os componentes são classes normais do .NET que definem a lógica de renderização da interface do usuário e os manipuladores de eventos do lado do cliente. Você pode criar aplicativos Web interativos avançados sem JavaScript.

Os componentes em Blazor normalmente são criados usando a sintaxe Razor, um blend natural de HTML e C#. Os componentes Razor são semelhantes às exibições do Razor Pages e do MVC, pois ambos usam Razor. Ao contrário de páginas e exibições, que são baseadas em um modelo de solicitação/resposta, os componentes são usados especificamente para manusear a composição da interface do usuário.

gRPC

gRPC:

  • É uma estrutura RPC popular de alto desempenho (chamada de procedimento remoto).

  • Oferece uma abordagem contract-first obstinada para o desenvolvimento de API.

  • Usa tecnologias modernas, como:

    • HTTP/2 para transporte.
    • Buffers de protocolo como a linguagem de descrição da interface.
    • Formato de serialização binária.
  • Fornece recursos como:

    • Autenticação
    • Streaming bidirecional e controle de fluxo.
    • Cancelamento e tempos limite.

A funcionalidade gRPC no ASP.NET Core 3.0 inclui:

  • Grpc.AspNetCore: uma estrutura do ASP.NET Core para hospedar serviços gRPC. O gRPC no ASP.NET Core é integrado aos recursos padrão do ASP.NET Core, como log, DI (injeção de dependência), autenticação e autorização.
  • Grpc.Net.Client: um cliente gRPC para .NET Core que se baseia no HttpClient clássico.
  • Grpc.Net.ClientFactory: integração do cliente gRPC com HttpClientFactory.

Para obter mais informações, confira Visão geral do gRPC no .NET.

SignalR

Confira Atualizar código SignalR para obter instruções de migração. SignalR agora usa System.Text.Json para serializar/desserializar mensagens ON JS. Confira Alternar para o Newtonsoft.Json para obter instruções para restaurar o serializador baseado em Newtonsoft.Json.

Nos clientes JavaScript e .NET para SignalR, o suporte foi adicionado para reconexão automática. Por padrão, o cliente tenta se reconectar imediatamente e tentar novamente após 2, 10 e 30 segundos, se necessário. Se o cliente se reconectar com êxito, ele receberá uma nova ID de conexão. A reconexão automática é aceita:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .withAutomaticReconnect()
    .build();

Os intervalos de reconexão podem ser especificados passando uma matriz de durações em milissegundos:

.withAutomaticReconnect([0, 3000, 5000, 10000, 15000, 30000])
//.withAutomaticReconnect([0, 2000, 10000, 30000]) The default intervals.

Uma implementação personalizada pode ser aprovada para controle total dos intervalos de reconexão.

Se a reconexão falhar após o último intervalo de reconexão:

  • O cliente considerará que a conexão está offline.
  • O cliente para de tentar se reconectar.

Durante as tentativas de reconexão, atualize a interface do usuário do aplicativo para notificar o usuário de que o sistema está tentando se reconectar.

Para fornecer comentários sobre a interface do usuário quando a conexão é interrompida, a API do cliente SignalR foi expandida para incluir os seguintes manipuladores de eventos:

  • onreconnecting: dá aos desenvolvedores a oportunidade de desabilitar a interface do usuário ou informar aos usuários que o aplicativo está offline.
  • onreconnected: dá aos desenvolvedores a oportunidade de atualizar a interface do usuário depois que a conexão é restabelecida.

O código a seguir usa onreconnecting para atualizar a interface do usuário ao tentar se conectar:

connection.onreconnecting((error) => {
    const status = `Connection lost due to error "${error}". Reconnecting.`;
    document.getElementById("messageInput").disabled = true;
    document.getElementById("sendButton").disabled = true;
    document.getElementById("connectionStatus").innerText = status;
});

O código a seguir usa onreconnected para atualizar a interface do usuário na conexão:

connection.onreconnected((connectionId) => {
    const status = `Connection reestablished. Connected.`;
    document.getElementById("messageInput").disabled = false;
    document.getElementById("sendButton").disabled = false;
    document.getElementById("connectionStatus").innerText = status;
});

SignalR 3.0 e posterior fornece um recurso personalizado para manipuladores de autorização, quando um método de hub exige autorização. O recurso é uma instância do HubInvocationContext. O HubInvocationContext inclui:

  • HubCallerContext
  • O nome do método de hub que está sendo invocado.
  • Os argumentos para o método de hub.

Considere o exemplo a seguir de um aplicativo de sala de chat que permite a entrada de várias organizações por meio do Azure Active Directory. Qualquer pessoa com uma conta Microsoft pode entrar no chat, mas apenas os membros da organização proprietária podem proibir usuários ou exibir históricos de chat dos usuários. O aplicativo pode restringir determinadas funcionalidades de usuários específicos.

public class DomainRestrictedRequirement :
    AuthorizationHandler<DomainRestrictedRequirement, HubInvocationContext>,
    IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
        DomainRestrictedRequirement requirement,
        HubInvocationContext resource)
    {
        if (context.User?.Identity?.Name == null)
        {
            return Task.CompletedTask;
        }

        if (IsUserAllowedToDoThis(resource.HubMethodName, context.User.Identity.Name))
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }

    private bool IsUserAllowedToDoThis(string hubMethodName, string currentUsername)
    {
        if (hubMethodName.Equals("banUser", StringComparison.OrdinalIgnoreCase))
        {
            return currentUsername.Equals("bob42@jabbr.net", StringComparison.OrdinalIgnoreCase);
        }

        return currentUsername.EndsWith("@jabbr.net", StringComparison.OrdinalIgnoreCase));
    }
}

No código anterior, DomainRestrictedRequirement atua como IAuthorizationRequirement personalizado. Como o parâmetro de recurso HubInvocationContext está sendo aprovado, a lógica interna pode:

  • Inspecione o contexto no qual o Hub está sendo chamado.
  • Tome decisões sobre como permitir que o usuário execute métodos de hub individuais.

Os métodos de Hub individuais podem ser marcados com o nome da política que o código verifica em tempo de execução. À medida que os clientes tentam chamar métodos de hub individuais, o manipulador DomainRestrictedRequirement executa e controla o acesso aos métodos. Com base na maneira como os controles DomainRestrictedRequirement acessam:

  • Todos os usuários conectados podem chamar o método SendMessage.
  • Somente os usuários que fizeram logon com um endereço de email @jabbr.net podem exibir os históricos dos usuários.
  • Somente o bob42@jabbr.net pode proibir os usuários da sala de chat.
[Authorize]
public class ChatHub : Hub
{
    public void SendMessage(string message)
    {
    }

    [Authorize("DomainRestricted")]
    public void BanUser(string username)
    {
    }

    [Authorize("DomainRestricted")]
    public void ViewUserHistory(string username)
    {
    }
}

A criação da política DomainRestricted pode envolver:

  • No Startup.cs, adicionar a nova política.
  • Forneça o requisito DomainRestrictedRequirement personalizado como parâmetro.
  • Registrar DomainRestricted com o middleware de autorização.
services
    .AddAuthorization(options =>
    {
        options.AddPolicy("DomainRestricted", policy =>
        {
            policy.Requirements.Add(new DomainRestrictedRequirement());
        });
    });

Os hubs SignalR usam o Roteamento de Ponto de Extremidade. A conexão de hub SignalR foi feita anteriormente de forma explícita:

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

Na versão anterior, os desenvolvedores precisavam conectar controladores, páginas Razor e hubs em vários locais. A conexão explícita resulta em uma série de segmentos de roteamento quase idênticos:

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

app.UseRouting(routes =>
{
    routes.MapRazorPages();
});

Os hubs SignalR 3.0 podem ser encaminhados por meio do roteamento de ponto de extremidade. Com o roteamento de ponto de extremidade, normalmente todo o roteamento pode ser configurado em UseRouting:

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

O SignalR ASP.NET Core 3.0 adicionou:

Streaming do cliente para o servidor. Com o streaming do cliente para o servidor, os métodos do lado do servidor podem ter instâncias de um IAsyncEnumerable<T> ou ChannelReader<T>. No exemplo do C# a seguir, o método UploadStream no Hub receberá um fluxo de cadeias de caracteres do cliente:

public async Task UploadStream(IAsyncEnumerable<string> stream)
{
    await foreach (var item in stream)
    {
        // process content
    }
}

Os aplicativos cliente do .NET podem passar uma instância IAsyncEnumerable<T> ou ChannelReader<T> como o argumento stream do método de Hub UploadStream acima.

Depois que o loop for for concluído e a função local for encerrada, a conclusão do fluxo será enviada:

async IAsyncEnumerable<string> clientStreamData()
{
    for (var i = 0; i < 5; i++)
    {
        var data = await FetchSomeData();
        yield return data;
    }
}

await connection.SendAsync("UploadStream", clientStreamData());

Os aplicativos cliente do JavaScript usam o SignalRSubject (ou um RxJS Assunto) para o argumento stream do método de Hub UploadStream acima.

let subject = new signalR.Subject();
await connection.send("StartStream", "MyAsciiArtStream", subject);

O código JavaScript pode usar o método subject.next para manipular cadeias de caracteres, à medida que são capturadas e estão prontas para serem enviadas ao servidor.

subject.next("example");
subject.complete();

Usando o código como os dois snippets anteriores, as experiências de streaming em tempo real podem ser criadas.

Na JSserialização ON

Agora o ASP.NET Core 3.0 usa System.Text.Json por padrão para JSserialização ON:

  • Lê e grava JSON de forma assíncrona.
  • É otimizado para texto UTF-8.
  • Normalmente, tem desempenho mais alto que Newtonsoft.Json.

Para adicionar o Json.NET ao ASP.NET Core 3.0, confira Adicionar suporte ao formato JSON baseado em Newtonsoft.Json.

Novas diretivas Razor

A lista a seguir contém novas diretivas Razor:

  • @attribute: a diretiva @attribute aplica o atributo fornecido à classe da página ou exibição gerada. Por exemplo, @attribute [Authorize].
  • @implements: a diretiva @implements implementa uma interface para a classe gerada. Por exemplo, @implements IDisposable.

IdentityO Server4 dá suporte à autenticação e autorização para APIs Web e SPAs

O ASP.NET Core 3.0 oferece autenticação em SPAs (Aplicativos de Página Única) usando o suporte para autorização de API Web. O Identity do ASP.NET Core para autenticação e armazenamento de usuários é combinado com o IdentityServer4 para implementar o OpenID Connect.

IdentityO Server4 é uma estrutura do OpenID Connect e OAuth 2.0 para ASP.NET Core 3.0. Ele oferece os recursos de segurança a seguir:

  • AaaS (autenticação como serviço)
  • SSO (logon único) em vários tipos de aplicativo
  • Controle de acesso para APIs
  • Federation Gateway

Para obter mais informações, confira a Identitydocumentação do Server4 ou Autenticação e autorização para SPAs.

Certificado e autenticação Kerberos

A autenticação de certificado exige:

  • Configurar o servidor para aceitar certificados.
  • Adicionar o middleware de autenticação no Startup.Configure.
  • Adicionar o serviço de autenticação de certificado em Startup.ConfigureServices.
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
            .AddCertificate();
    // Other service configuration removed.
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    // Other app configuration removed.
}

As opções de autenticação de certificado incluem a capacidade de:

  • Aceitar certificados autoassinados.
  • Verificar se há revogação de certificado.
  • Verificar se o certificado oferecido tem os sinalizadores de uso certos.

Uma entidade de usuário padrão é construída a partir das propriedades do certificado. A entidade de segurança do usuário contém um evento que permite complementar ou substituir a entidade de segurança. Para obter mais informações, consulte Configurar a autenticação de certificado no ASP.NET Core.

A Autenticação do Windows foi estendida para Linux e macOS. Nas versões anteriores, a Autenticação do Windows era limitada ao IIS e HTTP.sys. No ASP.NET Core 3.0, Kestrel tem a capacidade de usar Negotiate, Kerberos e NTLM no Windows, Linux e macOS para hosts ingressados no domínio do Windows. O suporte do Kestrel a esses esquemas de autenticação é fornecido pelo pacote NuGet Microsoft.AspNetCore.Authentication.Negotiate. Assim como acontece com os outros serviços de autenticação, configure todo o aplicativo de autenticação e configure o serviço:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate();
    // Other service configuration removed.
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    // Other app configuration removed.
}

Requisitos de host:

  • Os hosts do Windows devem ter SPNs (Nomes da Entidade de Serviço) adicionados à conta de usuário que hospeda o aplicativo.
  • Os computadores Linux e macOS devem ser ingressados no domínio.
    • Os SPNs devem ser criados para o processo da Web.
    • Os arquivos keytab devem ser gerados e configurados no computador host.

Para obter mais informações, confira Configurar autenticação do Windows no ASP.NET Core.

Alterações de modelo

Nos modelos de interface do usuário da Web (Razor Pages, MVC com controlador e exibições), o seguinte foi removido:

O modelo do Angular atualizado para usar o Angular 8.

O modelo de RCL (biblioteca de classes) Razor usa o desenvolvimento de componentes Razor por padrão. Uma nova opção de modelo no Visual Studio fornece suporte de modelo para páginas e exibições. Ao criar uma RCL com base no modelo em um shell de comando, passe a opção --support-pages-and-views (dotnet new razorclasslib --support-pages-and-views).

Host Genérico

Os modelos do ASP.NET Core 3.0 usam o Host Genérico do .NET no ASP.NET Core. As versões anteriores usavam WebHostBuilder. O uso do Host Genérico do .NET Core (HostBuilder) fornece uma melhor integração de aplicativos do ASP.NET Core com outros cenários de servidor que não são específicos da Web. Para obter mais informações, confira O HostBuilder substitui o WebHostBuilder.

Configuração do host

Antes do lançamento do ASP.NET Core 3.0, as variáveis de ambiente com o prefixo ASPNETCORE_ foram carregadas para a configuração do Host Da Web. No 3.0, AddEnvironmentVariables é usado para carregar variáveis de ambiente com o prefixo DOTNET_ para configuração de host com CreateDefaultBuilder.

Alterações na injeção do construtor de inicialização

O Host Genérico dá suporte apenas aos seguintes tipos para injeção de construtor Startup:

Todos os serviços ainda podem ser injetados diretamente como argumentos para o método Startup.Configure. Para obter mais informações, confira O Host Genérico restringe a injeção do construtor de inicialização (aspnet/Announcements #353).

Kestrel

  • A configuração Kestrel foi atualizada para a migração para o Host Genérico. Na versão 3.0, Kestrel é configurado no construtor de host da Web fornecido por ConfigureWebHostDefaults.
  • Os Adaptadores de Conexão foram removidos do Kestrel e substituídos pelo Middleware de Conexão, que é semelhante ao Middleware HTTP no pipeline do ASP.NET Core, mas para conexões de nível inferior.
  • A camada de transporte Kestrel foi exposta como uma interface pública no Connections.Abstractions.
  • A ambiguidade entre cabeçalhos e trailers foi resolvida movendo os cabeçalhos à direita para uma nova coleção.
  • APIs de E/S síncronas, como HttpRequest.Body.Read, são uma fonte comum de falta de thread que leva a falhas no aplicativo. No 3.0, AllowSynchronousIO está desabilitado por padrão.

Para obter mais informações, consulte Migrar do ASP.NET Core 2.2 para o 3.0.

HTTP/2 habilitado por padrão

O HTTP/2 está habilitado por padrão em Kestrel para pontos de extremidade HTTPS. O suporte a HTTP/2 para IIS ou HTTP.sys está habilitado quando há suporte no sistema operacional.

EventCounters sob solicitação

O EventSource de Hospedagem, Microsoft.AspNetCore.Hosting, emite os seguintes novos EventCounter tipos relacionados a solicitações de entrada:

  • requests-per-second
  • total-requests
  • current-requests
  • failed-requests

Roteamento de ponto de extremidade

O Roteamento de Ponto de Extremidade, que permite que estruturas (por exemplo, MVC) funcionem bem com middleware, foi aprimorado:

  • A ordem do middleware e dos pontos de extremidade é configurável no pipeline de processamento de solicitação de Startup.Configure.
  • Os pontos de extremidade e o middleware são compatíveis com outras tecnologias baseadas em ASP.NET Core, como as Verificações de Integridade.
  • Os pontos de extremidade podem implementar uma política, como CORS ou autorização, no middleware e no MVC.
  • Os filtros e atributos podem ser colocados em métodos nos controladores.

Saiba mais em Roteamento no ASP.NET Core.

Verificações de Integridade

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

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

Os pontos de extremidade de Verificações de Integridade podem:

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

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

Pipes em HttpContext

Agora é possível ler o corpo da solicitação e gravar o corpo da resposta usando a API System.IO.Pipelines. A propriedade HttpRequest.BodyReader fornece um PipeReader que pode ser usado para ler o corpo da solicitação. A propriedade HttpResponse.BodyWriter fornece um PipeWriter que pode ser usado para gravar o corpo da resposta. HttpRequest.BodyReader é um análogo do fluxo HttpRequest.Body. HttpResponse.BodyWriter é um análogo do fluxo HttpResponse.Body.

Relatórios de erros aprimorados no IIS

Os erros de inicialização ao hospedar aplicativos do ASP.NET Core no IIS agora produzem dados de diagnóstico mais avançados. Esses erros são relatados ao Log de Eventos do Windows com rastreamentos de pilha, sempre que aplicável. Além disso, todos os avisos, erros e exceções sem tratamento são registrados no Log de Eventos do Windows.

Serviço de Trabalho e SDK de Trabalho

O .NET Core 3.0 apresenta o novo modelo de aplicativo do Serviço de Trabalho. Este modelo fornece um ponto de partida para gravar serviços de execução prolongada no .NET Core.

Para obter mais informações, consulte:

Aprimoramentos do Middleware de Cabeçalhos Encaminhados

Nas versões anteriores do ASP.NET Core, chamar UseHsts e UseHttpsRedirection era problemático quando implantado em um Linux do Azure ou atrás de qualquer proxy reverso diferente do IIS. A correção para versões anteriores está documentada em Encaminhar o esquema para proxies reversos Linux e não IIS.

Esse cenário foi corrigido no ASP.NET Core 3.0. O host habilita o Middleware de Cabeçalhos Encaminhados quando a variável de ambiente ASPNETCORE_FORWARDEDHEADERS_ENABLED é definida como true. ASPNETCORE_FORWARDEDHEADERS_ENABLED é definido como true em nossas imagens de contêiner.

Melhorias de desempenho

O ASP.NET Core 3.0 inclui muitos aprimoramentos que reduzem o uso de memória e melhoram a taxa de transferência:

  • Redução no uso de memória ao usar o contêiner de injeção de dependência interno para serviços com escopo.
  • Redução nas alocações em toda a estrutura, incluindo cenários de middleware e roteamento.
  • Redução no uso de memória para conexões WebSocket.
  • Redução de memória e melhorias da taxa de transferência para conexões HTTPS.
  • Novo serializador JSON otimizado e totalmente assíncrono.
  • Redução no uso de memória e melhorias da taxa de transferência na análise de formulários.

O ASP.NET Core 3.0 só é executado no .NET Core 3.0

A partir do ASP.NET Core 3.0, o .NET Framework não é mais uma estrutura de destino com suporte. Os projetos direcionados ao .NET Framework podem continuar contando com suporte completo ao usar a versão .NET Core 2.1 LTS. A maioria dos pacotes relacionados do ASP.NET Core 2.1.x terá suporte indefinidamente, além do período de LTS de três anos para o .NET Core 2.1.

Para obter informações de migração, confira Portabilidade do código do .NET Framework para o .NET Core.

Usar a estrutura compartilhada do ASP.NET Core

A estrutura compartilhada do ASP.NET Core 3.0, contida no metapacote Microsoft.AspNetCore.App, não requer mais um elemento explícito <PackageReference /> no arquivo de projeto. A estrutura compartilhada é referenciada automaticamente ao usar o SDK Microsoft.NET.Sdk.Web no arquivo de projeto:

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

Assemblies removidos da estrutura compartilhada do ASP.NET Core

Os assemblies mais importantes removidos da estrutura compartilhada do ASP.NET Core 3.0 são:

Para obter uma lista completa dos assemblies removidos da estrutura compartilhada, confira Assemblies removidos do Microsoft.AspNetCore.App 3.0. Para obter mais informações sobre a motivação dessa alteração, confira Últimas alterações no Microsoft.AspNetCore.App na versão 3.0 e Uma primeira olhada nas próximas alterações do ASP.NET Core 3.0.