Compartilhar via


Novidades no ASP.NET Core 10.0

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

Este artigo será atualizado à medida que novas versões prévias forem disponibilizadas. Consulte a página de comunicados do Asp.Net Core até que esta página seja atualizada.

Blazor

Esta seção descreve os novos recursos do Blazor.

parâmetro QuickGridRowClass

Aplique uma classe de estilo a uma linha da grade com base no item da linha usando o novo parâmetro RowClass. No exemplo a seguir, o método GetRowCssClass é chamado em cada linha para aplicar condicionalmente uma classe de folha de estilos com base no item de linha:

<QuickGrid ... RowClass="GetRowCssClass">
    ...
</QuickGrid>

@code {
    private string GetRowCssClass(MyGridItem item) =>
        item.IsArchived ? "row-archived" : null;
}

Para obter mais informações, consulte ASP.NET Core Blazor `QuickGrid` componente.

Blazor script como recurso web estático

Em versões anteriores do .NET, o script Blazor é fornecido de um recurso inserido na estrutura compartilhada do ASP.NET Core. No .NET 10 ou posterior, o script Blazor é servido como um ativo da Web estático com compactação automática e impressão digital.

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

Destaques do esquema de rota

O atributo [Route] agora dá suporte ao realce de sintaxe de rota para ajudar a visualizar a estrutura do modelo de rota:

O padrão de modelo de rota de um atributo de rota para o valor do contador mostra destaque de sintaxe

Anteriormente, NavigationManager.NavigateTo rolava até a parte superior da página para navegação na mesma página. Esse comportamento foi alterado no .NET 10 para que o navegador não role mais para a parte superior da página ao navegar para a mesma página. Isso significa que o viewport não é mais redefinido ao fazer atualizações no endereço da página atual, como ao alterar a string de consulta ou o fragmento.

Componente de IU de reconexão adicionado ao modelo de projeto Blazor Web App

O modelo de projeto Blazor Web App agora inclui um componente ReconnectModal, incluindo arquivos JavaScript e folhas de estilos agrupados, para melhorar o controle do desenvolvedor sobre a IU de reconexão quando o cliente perde a conexão WebSocket com o servidor. O componente não insere estilos programaticamente, garantindo a conformidade com configurações de CSP (Política de Segurança de Conteúdo) mais rigorosas para a política de style-src. Em versões anteriores, a interface do usuário de reconexão padrão foi criada pela estrutura de uma maneira que poderia causar violações de CSP. Observe que a interface do usuário de reconexão padrão ainda é usada como alternativa quando o aplicativo não define a interface do usuário de reconexão, como ao usar o componente ReconnectModal do modelo de projeto ou um componente personalizado semelhante.

Novos recursos de IU de reconexão:

  • Além de indicar o estado de reconexão definindo uma classe CSS específica no elemento de interface de reconexão, o novo evento components-reconnect-state-changed é disparado para alterações de estado de reconexão.
  • O código pode diferenciar melhor os estágios do processo de reconexão com o novo estado de reconexão "retrying", indicado pela classe CSS e pelo novo evento.

Para obter mais informações, confira as diretrizes BlazorSignalRdo ASP.NET Core.

Ignorar a cadeia de caracteres e o fragmento de consulta ao usar NavLinkMatch.All

O componente NavLink agora ignora a cadeia de caracteres de consulta e o fragmento ao usar o valor NavLinkMatch.All para o parâmetro Match. Isso significa que o link mantém a classe active se o caminho da URL corresponder, mas a cadeia de caracteres de consulta ou o fragmento mudarem. Para reverter para o comportamento original, use o Microsoft.AspNetCore.Components.Routing.NavLink.EnableMatchAllForQueryStringAndFragmentAppContext interruptor definido para true.

Você também pode substituir o método ShouldMatch em NavLink para personalizar o comportamento correspondente:

public class CustomNavLink : NavLink
{
    protected override bool ShouldMatch(string currentUriAbsolute)
    {
        // Custom matching logic
    }
}

Para obter mais informações, confira Roteamento e navegação do Blazor no ASP.NET Core.

Fechar opções de coluna QuickGrid

Agora você pode fechar a UI das opções da coluna QuickGrid usando o novo método CloseColumnOptionsAsync.

O exemplo a seguir usa o método CloseColumnOptionsAsync para fechar a interface do usuário das opções de coluna assim que o filtro de título é aplicado:

<QuickGrid @ref="movieGrid" Items="movies">
    <PropertyColumn Property="@(m => m.Title)" Title="Title">
        <ColumnOptions>
            <input type="search" @bind="titleFilter" placeholder="Filter by title" 
                @bind:after="@(() => movieGrid.CloseColumnOptionsAsync())" />
        </ColumnOptions>
    </PropertyColumn>
    <PropertyColumn Property="@(m => m.Genre)" Title="Genre" />
    <PropertyColumn Property="@(m => m.ReleaseYear)" Title="Release Year" />
</QuickGrid>

@code {
    private QuickGrid<Movie>? movieGrid;
    private string titleFilter = string.Empty;
    private IQueryable<Movie> movies = new List<Movie> { ... }.AsQueryable();
    private IQueryable<Movie> filteredMovies => 
        movies.Where(m => m.Title!.Contains(titleFilter));
}

O streaming de resposta é de adesão opcional e como optar por não participar

Em versões anteriores de Blazor, o streaming de resposta para solicitações HttpClient era opcional. Agora, o streaming de resposta está habilitado por padrão.

Essa é uma alteração significativa porque a chamada de HttpContent.ReadAsStreamAsync para um HttpResponseMessage.Content (response.Content.ReadAsStreamAsync()) retorna um BrowserHttpReadStream e não mais um MemoryStream. BrowserHttpReadStream não dá suporte a operações síncronas, como Stream.Read(Span<Byte>). Se o código usar operações síncronas, você poderá optar por não usar o streaming de resposta ou copiar o Stream para um MemoryStream você mesmo.

Para desativar o streaming de resposta globalmente, defina a variável de ambiente DOTNET_WASM_ENABLE_STREAMING_RESPONSE como false ou 0.

Para desativar o streaming de resposta para uma solicitação individual, defina SetBrowserResponseStreamingEnabled como false no HttpRequestMessage (requestMessage no exemplo a seguir).

requestMessage.SetBrowserResponseStreamingEnabled(false);

Para obter mais informações, consulte HttpClient e HttpRequestMessage com as opções de solicitação da API Fetch (artigo Chamada da API Web).

Impressão digital do lado do cliente

No ano passado, o lançamento do .NET 9 introduziu a impressão digital de ativos estáticos do lado do servidor em Blazor Web Apps, com a introdução de convenções de roteamento de ponto de extremidade de Mapear Ativos Estáticos (MapStaticAssets), do ImportMapcomponente e da propriedade ComponentBase.Assets (@Assets["..."]) para resolver módulos JavaScript com rastreamento. Para o .NET 10, você pode optar por ativar a impressão digital feita no lado do cliente de módulos JavaScript para aplicativos independentes Blazor WebAssembly.

Em aplicativos Blazor WebAssembly autônomos, durante a compilação/publicação, a estrutura substitui espaços reservados em index.html por valores calculados durante a compilação para ativos estáticos de impressão digital. Uma impressão digital é colocada no nome do arquivo de script blazor.webassembly.js.

As alterações a seguir devem ser feitas no wwwwoot/index.html arquivo para adotar o recurso de impressão digital. O modelo de projeto autônomo Blazor WebAssembly será atualizado para incluir essas alterações em uma versão prévia futura:

<head>
    ...
+   <script type="importmap"></script>
</head>

<body>
    ...
-   <script src="_framework/blazor.webassembly.js"></script>
+   <script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script>
</body>

</html>

No arquivo de projeto (.csproj), adicione a propriedade <WriteImportMapToHtml> definida como true:

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

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
+   <WriteImportMapToHtml>true</WriteImportMapToHtml>
  </PropertyGroup>
</Project>

Para identificar módulos adicionais JS em aplicativos independentes Blazor WebAssembly, use a propriedade <StaticWebAssetFingerprintPattern> no arquivo de projeto do aplicativo (.csproj).

No exemplo a seguir, uma impressão digital é adicionada para todos os arquivos fornecidos pelo .mjs desenvolvedor no aplicativo:

<StaticWebAssetFingerprintPattern Include="JSModule" Pattern="*.mjs" 
  Expression="#[.{fingerprint}]!" />

Os arquivos são colocados automaticamente no mapa de importação:

  • Automaticamente para CSR Blazor Web App.
  • Ao optar pela impressão digital do módulo em aplicativos autônomos Blazor WebAssembly de acordo com as instruções anteriores.

Ao resolver a importação para a interoperabilidade do JavaScript, o mapa de importação é usado pelo navegador para resolver arquivos com impressão digital.

Definir o ambiente em aplicativos autônomos Blazor WebAssembly

O Properties/launchSettings.json arquivo não é mais usado para controlar o ambiente em aplicativos autônomos Blazor WebAssembly .

A partir do .NET 10, defina o ambiente com a <WasmApplicationEnvironmentName> propriedade no arquivo de projeto do aplicativo (.csproj).

O exemplo a seguir define o ambiente do aplicativo como Staging:

<WasmApplicationEnvironmentName>Staging</WasmApplicationEnvironmentName>

Os ambientes padrão são:

  • Development para compilação.
  • Production para publicação.

Alteração do nome do arquivo de configuração de inicialização

O arquivo de configuração de inicialização está alterando nomes de blazor.boot.json para dotnet.boot.js. Essa alteração de nome afeta apenas os desenvolvedores que estão interagindo diretamente com o arquivo, como quando os desenvolvedores estão:

Modelo declarativo para manter o estado de componentes e serviços

Agora você pode especificar declarativamente o estado para persistir em componentes e serviços usando o atributo [SupplyParameterFromPersistentComponentState]. As propriedades com esse atributo são mantidas automaticamente usando o PersistentComponentState serviço durante a pré-geração. O estado é recuperado quando o componente é renderizado interativamente ou o serviço é instanciado.

Nas versões anteriores Blazor, manter o estado do componente durante a pré-geração usando o serviço PersistentComponentState envolvia uma quantidade significativa de código, como demonstra o exemplo a seguir:

@page "/movies"
@implements IDisposable
@inject IMovieService MovieService
@inject PersistentComponentState ApplicationState

@if (MoviesList == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <QuickGrid Items="MoviesList.AsQueryable()">
        ...
    </QuickGrid>
}

@code {
    public List<Movie>? MoviesList { get; set; }
    private PersistingComponentStateSubscription? persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        if (!ApplicationState.TryTakeFromJson<List<Movie>>(nameof(MoviesList), 
            out var movies))
        {
            MoviesList = await MovieService.GetMoviesAsync();
        }
        else
        {
            MoviesList = movies;
        }

        persistingSubscription = ApplicationState.RegisterOnPersisting(() =>
        {
            ApplicationState.PersistAsJson(nameof(MoviesList), MoviesList);
            return Task.CompletedTask;
        });
    }

    public void Dispose() => persistingSubscription?.Dispose();
}

Esse código agora pode ser simplificado usando o novo modelo declarativo:

@page "/movies"
@inject IMovieService MovieService

@if (MoviesList == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <QuickGrid Items="MoviesList.AsQueryable()">
        ...
    </QuickGrid>
}

@code {
    [SupplyParameterFromPersistentComponentState]
    public List<Movie>? MoviesList { get; set; }

    protected override async Task OnInitializedAsync()
    {
        MoviesList ??= await MovieService.GetMoviesAsync();
    }
}

Para mais informações, confira Pré-renderizar componentes Razor do ASP.NET Core. Notas adicionais de implementação de API, que estão sujeitas a alterações a qualquer momento, estão disponíveis no [Blazor] Suporte para manter declarativamente o estado de componentes e serviços (dotnet/aspnetcore nº 60634).

Blazor Hybrid

Esta seção descreve os novos recursos do Blazor Hybrid.

Novo .NET MAUIBlazor Hybrid com um artigo e um exemplo do Blazor Web App e do ASP.NET Core Identity

Um novo artigo e um aplicativo de exemplo foram adicionados para .NET MAUIBlazor Hybrid e Aplicativo Web usando ASP.NET Core Identity.

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

SignalR

Esta seção descreve os novos recursos do SignalR.

APIs mínimas

Esta seção descreve novos recursos para APIs mínimas.

Tratar a cadeia de caracteres vazia em postagens de formulário como nulo para tipos de valor que permitem valor nulo

Ao usar o atributo [FromForm] com um objeto complexo em APIs mínimas, valores de cadeias de caracteres vazias em uma postagem de formulário agora são convertidos em null em vez de causar uma falha de análise. Esse comportamento corresponde à lógica de processamento de postagens de formulário não associadas a objetos complexos em APIs mínimas.

using Microsoft.AspNetCore.Http;

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapPost("/todo", ([FromForm] Todo todo) => TypedResults.Ok(todo));

app.Run();

public class Todo
{
  public int Id { get; set; }
  public DateOnly? DueDate { get; set; } // Empty strings map to `null`
  public string Title { get; set; }
  public bool IsCompleted { get; set; }
}

Obrigado a @nvmkpk por contribuir com essa mudança!

Suporte à validação em APIs mínimas

O suporte para validação em APIs Mínimas agora está disponível. Esse recurso permite que você solicite a validação dos dados enviados para seus endpoints da API. Habilitar a validação permite que o runtime do ASP.NET Core execute as validações definidas no:

  • Consulta
  • Cabeçalho
  • Corpo da solicitação

As validações são definidas usando atributos no DataAnnotations namespace. Os desenvolvedores personalizam o comportamento do sistema de validação:

  • Criando implementações de atributo personalizado [Validation] .
  • Implementando a IValidatableObject interface para lógica de validação complexa.

Se a validação falhar, o runtime retornará uma resposta 400 Solicitação incorreta com detalhes dos erros de validação.

Habilitar o suporte de validação interna para APIs mínimas

Habilite o suporte de validação interna para APIs mínimas chamando o AddValidation método de extensão para registrar os serviços necessários no contêiner de serviço para seu aplicativo:

builder.Services.AddValidation();

A implementação descobre automaticamente tipos definidos em manipuladores mínimos de API ou como tipos base de tipos definidos em manipuladores mínimos de API. Um filtro de ponto de extremidade executa a validação nesses tipos e é adicionado para cada ponto de extremidade.

A validação pode ser desabilitada para pontos de extremidade específicos usando o DisableValidation método de extensão, como no exemplo a seguir:

app.MapPost("/products",
    ([EvenNumber(ErrorMessage = "Product ID must be even")] int productId, [Required] string name)
        => TypedResults.Ok(productId))
    .DisableValidation();

Suporte para eventos enviados do servidor (SSE)

ASP.NET Core agora dá suporte ao retorno de um resultado ServerSentEvents usando a API TypedResults.ServerSentEvents . Esse recurso tem suporte em APIs mínimas e aplicativos baseados em controlador.

Server-Sent Eventos é uma tecnologia de push de servidor que permite que um servidor envie um fluxo de mensagens de evento para um cliente por meio de uma única conexão HTTP. No .NET, as mensagens de evento são representadas como SseItem<T> objetos, que podem conter um tipo de evento, uma ID e um conteúdo de dados do tipo T.

A classe TypedResults tem um novo método estático chamado ServerSentEvents que pode ser usado para retornar um ServerSentEvents resultado. O primeiro parâmetro para esse método é um IAsyncEnumerable<SseItem<T>> que representa o fluxo de mensagens de evento a serem enviadas ao cliente.

O exemplo a seguir ilustra como usar a TypedResults.ServerSentEvents API para retornar um fluxo de eventos de freqüência cardíaca como objetos JSON para o cliente:

app.MapGet("/json-item", (CancellationToken cancellationToken) =>
{
    async IAsyncEnumerable<HeartRateRecord> GetHeartRate(
        [EnumeratorCancellation] CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            var heartRate = Random.Shared.Next(60, 100);
            yield return HeartRateRecord.Create(heartRate);
            await Task.Delay(2000, cancellationToken);
        }
    }

    return TypedResults.ServerSentEvents(GetHeartRate(cancellationToken),
                                                  eventType: "heartRate");
});

Para obter mais informações, consulte:

OpenAPI

Esta seção descreve novos recursos para OpenAPI.

Suporte ao OpenAPI 3.1

ASP.NET Core adicionou suporte para gerar documentos OpenAPI versão 3.1 no .NET 10. Apesar do pequeno aumento na versão, o OpenAPI 3.1 é uma atualização significativa para a especificação OpenAPI, em particular com suporte total para Rascunho do esquema JSON 2020-12.

Algumas das alterações que você verá no documento OpenAPI gerado incluem:

  • Tipos anuláveis não têm mais a propriedade nullable: true no esquema.
  • Em vez de uma propriedade nullable: true, eles têm uma palavra-chave type cujo valor é uma matriz que inclui null como um dos tipos.
  • Propriedades ou parâmetros definidos como um C# int ou long agora aparecem no documento OpenAPI gerado sem o type: integer campo e têm um pattern campo que limita o valor a dígitos. Isso acontece quando a propriedade NumberHandling no JsonSerializerOptions é configurada para AllowReadingFromString, o padrão para aplicativos Web do ASP.NET Core. Para permitir que C# int e long sejam representados no documento OpenAPI como type: integer, defina a propriedade NumberHandling como long.

Com esse recurso, a versão padrão do OpenAPI para documentos gerados é3.1. A versão pode ser alterada ajustando explicitamente a propriedade OpenApiVersion do OpenApiOptions no parâmetro delegado configureOptions de AddOpenApi.

builder.Services.AddOpenApi(options =>
{
    // Specify the OpenAPI version to use.
    options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_0;
});

Ao gerar o documento OpenAPI no momento do build, a versão do OpenAPI pode ser selecionada definindo o --openapi-version no item OpenApiGenerateDocumentsOptions MSBuild.

    <!-- Configure build-time OpenAPI generation to produce an OpenAPI 3.0 document. -->
    <OpenApiGenerateDocumentsOptions>--openapi-version OpenApi3_0</OpenApiGenerateDocumentsOptions>

O suporte ao OpenAPI 3.1 foi adicionado principalmente no seguinte PR.

Alterações significativas no OpenAPI 3.1

O suporte para OpenAPI 3.1 requer uma atualização para a biblioteca de OpenAPI.NET subjacente para uma nova versão principal, 2.0. Esta nova versão tem algumas alterações significativas da versão anterior. As alterações significativas podem afetar aplicativos se eles tiverem quaisquer transformadores de documento, operação ou esquema. Alterações significativas nesta iteração incluem o seguinte:

  • Entidades dentro do documento OpenAPI, como operações e parâmetros, são digitadas como interfaces. Existem implementações concretas para as variantes inseridas e referenciadas de uma entidade. Por exemplo, um IOpenApiSchema pode ser um OpenApiSchema embutido ou um OpenApiSchemaReference que aponta para um esquema definido em outro lugar no documento.
  • A propriedade Nullable foi removida do tipo OpenApiSchema. Para determinar se um tipo é anulável, avalie se a propriedade OpenApiSchema.Type define JsonSchemaType.Null.

Uma das mudanças mais significativas é que a classe OpenApiAny foi descartada em favor do uso JsonNode diretamente. Os transformadores que usam OpenApiAny precisam ser atualizados para usar JsonNode. A seguinte diferença mostra as alterações no transformador de esquema do .NET 9 para o .NET 10:

options.AddSchemaTransformer((schema, context, cancellationToken) =>
{
    if (context.JsonTypeInfo.Type == typeof(WeatherForecast))
    {
-       schema.Example = new OpenApiObject
+       schema.Example = new JsonObject
        {
-           ["date"] = new OpenApiString(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")),
+           ["date"] = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd"),
-           ["temperatureC"] = new OpenApiInteger(0),
+           ["temperatureC"] = 0,
-           ["temperatureF"] = new OpenApiInteger(32),
+           ["temperatureF"] = 32,
-           ["summary"] = new OpenApiString("Bracing"),
+           ["summary"] = "Bracing",
        };
    }
    return Task.CompletedTask;
});

Observe que essas alterações são necessárias mesmo ao configurar apenas a versão do OpenAPI para 3.0.

OpenAPI em YAML

ASP.NET agora dá suporte ao serviço do documento OpenAPI gerado no formato YAML. YAML pode ser mais conciso do que JSON, eliminando chaves curvas e aspas quando essas podem ser inferidas. O YAML também dá suporte a cadeias de caracteres de várias linhas, que podem ser úteis para descrições longas.

Para configurar um aplicativo para atender ao documento OpenAPI gerado no formato YAML, especifique o ponto de extremidade na chamada MapOpenApi com um sufixo ".yaml" ou ".yml", conforme mostrado no exemplo a seguir:

app.MapOpenApi("/openapi/{documentName}.yaml");

Suporte para:

  • Atualmente, o YAML só está disponível para o OpenAPI servido no Ponto de Extremidade de API.
  • A geração de documentos OpenAPI no formato YAML no momento da compilação é adicionada em uma versão prévia futura.

Consulte este PR, o qual adicionou suporte para exibir o documento OpenAPI gerado em formato YAML.

Descrição da resposta em ProducesResponseType

Os atributos ProducesAttribute, ProducesResponseTypeAttributee ProducesDefaultResponseType agora aceitam um parâmetro de cadeia de caracteres opcional, Description, que definirá a descrição da resposta. Veja um exemplo:

[HttpGet(Name = "GetWeatherForecast")]
[ProducesResponseType<IEnumerable<WeatherForecast>>(StatusCodes.Status200OK,
                   Description = "The weather forecast for the next 5 days.")]
public IEnumerable<WeatherForecast> Get()
{

E o OpenAPI gerado:

        "responses": {
          "200": {
            "description": "The weather forecast for the next 5 days.",
            "content": {

Contribuição da Comunidade por Sander ten Brinke

Preencher comentários de documentos XML no documento OpenAPI

A geração de documentos OpenAPI de ASP.NET Core agora incluirá metadados de comentários de documentação XML nas definições de métodos, classes e membros no documento OpenAPI. Você deve habilitar os comentários do documento XML em seu arquivo de projeto para usar esse recurso. Você pode fazer isso adicionando a seguinte propriedade ao arquivo de projeto:

  <PropertyGroup>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>

No tempo de compilação, o pacote OpenAPI utilizará um gerador de código-fonte para descobrir comentários XML no assembly da aplicação atual e quaisquer referências de projeto, emitindo código-fonte para inseri-los no documento por meio de um transformador de documento OpenAPI.

Observe que o processo de build do C# não captura comentários de documento XML colocados em expresões lambda, portanto, para usar comentários de documento XML para adicionar metadados a um ponto de extremidade de API mínimo, você deve definir o manipulador de ponto de extremidade como um método, colocar os comentários do documento XML sobre o método e, em seguida, referenciar esse método do método MapXXX. Por exemplo, para usar comentários de documento XML para adicionar metadados a um ponto de extremidade de API mínimo originalmente definido como uma expressão lambda:

app.MapGet("/hello", (string name) =>$"Hello, {name}!");

Altere a chamada MapGet para fazer referência a um método:

app.MapGet("/hello", Hello);

Defina o método Hello com comentários de documento XML:

static partial class Program
{
    /// <summary>
    /// Sends a greeting.
    /// </summary>
    /// <remarks>
    /// Greeting a person by their name.
    /// </remarks>
    /// <param name="name">The name of the person to greet.</param>
    /// <returns>A greeting.</returns>
    public static string Hello(string name)
    {
        return $"Hello, {name}!";
    }
}

No exemplo anterior, o método Hello é adicionado à classe Program, mas você pode adicioná-lo a qualquer classe em seu projeto.

O exemplo anterior ilustra os comentários dos documentos XML <summary>, <remarks>e <param>. Para obter mais informações sobre comentários de documentos XML, incluindo todas as tags com suporte, consulte a documentação do C#.

Como a funcionalidade principal é fornecida por meio de um gerador de origem, ela pode ser desabilitada adicionando o MSBuild a seguir ao arquivo de projeto.

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.2.*" GeneratePathProperty="true" />
</ItemGroup>

<Target Name="DisableCompileTimeOpenApiXmlGenerator" BeforeTargets="CoreCompile">
  <ItemGroup>
    <Analyzer Remove="$(PkgMicrosoft_AspNetCore_OpenApi)/analyzers/dotnet/cs/Microsoft.AspNetCore.OpenApi.SourceGenerators.dll" />
  </ItemGroup>
</Target>

O gerador de origem processa os arquivos XML incluídos na propriedade AdditionalFiles. Para adicionar (ou remover), as fontes modificam a propriedade da seguinte maneira:

<Target Name="AddXmlSources" BeforeTargets="CoreCompile">
  <ItemGroup>
    <AdditionalFiles Include="$(PkgSome_Package)/lib/net10.0/Some.Package.xml" />
  </ItemGroup>
</Target>

Microsoft.AspNetCore.OpenApi adicionado ao modelo de API Web do ASP.NET Core (AOT Nativo)

O modelo de projeto da API Web do ASP.NET Core (AOT Nativo) (nome webapiaotcurto) agora inclui suporte para a geração de documentos OpenAPI usando o Microsoft.AspNetCore.OpenApi pacote por padrão. Esse suporte é desabilitado usando o --no-openapi sinalizador ao criar um novo projeto.

Esta foi uma contribuição da comunidade por @sander1095. Obrigado por essa contribuição!

Autenticação e autorização

Esta seção descreve novos recursos para autenticação e autorização.

Métricas de autenticação e autorização

As métricas foram adicionadas para determinados eventos de autenticação e autorização no ASP.NET Core. Com essa alteração, agora você pode obter métricas para os seguintes eventos:

  • Autenticação:
    • Duração da solicitação autenticada
    • Contagem de desafios
    • Contagem de proibições
    • Contagem de entradas
    • Contagem de desconexões
  • Autorização:
    • Contagem de solicitações que exigem autorização

A imagem a seguir mostra um exemplo da métrica de duração da solicitação autenticada no painel do Aspire:

Duração da solicitação autenticada no painel do Aspire

Para obter mais informações, consulte ASP.NET Principais métricas de Autorização e Autenticação.

Variado

Esta seção descreve novos recursos diversos no ASP.NET Core 10.0.

Melhor suporte para testar aplicativos com instruções de nível superior

O .NET 10 agora tem melhor suporte para testar aplicativos que usam instruções de nível superior. Anteriormente, os desenvolvedores tinham que adicionar manualmente public partial class Program ao arquivo de Program.cs para que o projeto de teste pudesse referenciar o Program class. public partial class Program foi necessário porque o recurso de instrução de nível superior no C# 9 gerou um Program class que foi declarado como interno.

No .NET 10, utiliza-se um gerador de origem para gerar a declaração de public partial class Program caso o programador não a tenha declarado explicitamente. Além disso, um analisador foi adicionado para detectar quando public partial class Program é declarado explicitamente e aconselha o desenvolvedor a removê-lo.

Imagem

Os seguintes PRs contribuíram para esta funcionalidade:

Detectar se a URL é local usando RedirectHttpResult.IsLocalUrl

Use o novo método auxiliar RedirectHttpResult.IsLocalUrl(url) para detectar se uma URL é local. Uma URL será considerada local se o seguinte for verdadeiro:

URLs que utilizam caminhos virtuais"~/" são considerados locais também.

IsLocalUrl é útil para validar URLs antes de redirecionar para elas para evitar ataques de redirecionamento aberto.

if (RedirectHttpResult.IsLocalUrl(url))
{
    return Results.LocalRedirect(url);
}

Obrigado @martincostello por esta contribuição!