Condividi tramite


Novità di ASP.NET Core 10.0

Questo articolo illustra le modifiche più significative in ASP.NET Core 10.0 con collegamenti alla documentazione pertinente.

Questo articolo verrà aggiornato man mano che vengono rese disponibili nuove versioni di anteprima. Consultare la pagina degli annunci di Asp.Net Core fino all'aggiornamento di questa pagina.

Blazor

In questa sezione vengono descritte le nuove funzionalità per Blazor.

parametro QuickGridRowClass

Applicare una classe del foglio di stile a una riga della griglia in base all'elemento di riga utilizzando il nuovo parametro RowClass. Nell'esempio seguente viene chiamato il metodo GetRowCssClass su ogni riga per applicare in modo condizionale una classe del foglio di stile in base all'elemento di riga:

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

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

Per ulteriori informazioni, consultare ASP.NET Core Blazor `QuickGrid` componente.

Blazor script come asset web statico

Nelle versioni precedenti di .NET, lo script Blazor viene gestito da una risorsa incorporata nel framework condiviso ASP.NET Core. In .NET 10 o versione successiva, lo script Blazor viene utilizzato come asset Web statico con compressione e impronta digitale automatici.

Per altre informazioni, vedere le risorse seguenti:

Punti salienti del modello di percorso

L'attributo [Route] supporta ora l'evidenziazione della sintassi di route per visualizzare la struttura del modello di route:

modello di attributo di route per il valore del contatore mostra l'evidenziazione della sintassi

SignalR

In questa sezione vengono descritte le nuove funzionalità per SignalR.

API minimali

Questa sezione descrive le nuove funzionalità per le API minime.

OpenAPI

Questa sezione descrive le nuove funzionalità per OpenAPI.

Supporto di OpenAPI 3.1

ASP.NET Core ha aggiunto il supporto per la generazione di documenti OpenAPI versione 3.1 in .NET 10. Nonostante l'urto della versione secondaria, OpenAPI 3.1 è un aggiornamento significativo della specifica OpenAPI, in particolare con il supporto completo per bozza di schema JSON 2020-12.

Alcune delle modifiche che verranno visualizzate nel documento OpenAPI generato includono:

  • I tipi nullable non hanno più la proprietà nullable: true nello schema.
  • Anziché una proprietà nullable: true, hanno una parola chiave type il cui valore è una matrice che include null come uno dei tipi.

Con questa funzionalità, la versione OpenAPI predefinita per i documenti generati è3.1. La versione può essere modificata impostando in modo esplicito la proprietà OpenApiVersion del OpenApiOptions nel parametro delegato configureOptions di AddOpenApi.

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

Quando si genera il documento OpenAPI in fase di compilazione, è possibile selezionare la versione OpenAPI impostando il --openapi-version nell'elemento OpenApiGenerateDocumentsOptions MSBuild.

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

Il supporto di OpenAPI 3.1 è stato principalmente aggiunto nella seguente pull request .

Modifiche di rilievo di OpenAPI 3.1

Il supporto per OpenAPI 3.1 richiede un aggiornamento alla libreria OpenAPI.NET sottostante a una nuova versione principale, 2.0. Questa nuova versione presenta alcune modifiche che rompono la compatibilità rispetto alla versione precedente. Le modifiche importanti possono influire sulle app se hanno documenti, operazioni o trasformatori di schemi.

Una delle modifiche più significative è che la classe OpenApiAny è stata eliminata a favore dell'uso diretto di JsonNode. I trasformatori che usano OpenApiAny devono essere aggiornati per usare JsonNode. La diff seguente illustra le modifiche apportate al trasformatore di schema da .NET 9 a .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;
});

Si noti che queste modifiche sono necessarie anche quando si configura solo la versione OpenAPI alla versione 3.0.

OpenAPI in Yaml

ASP.NET supporta ora la gestione del documento OpenAPI generato in formato YAML. YAML può essere più conciso di JSON, eliminando parentesi graffe e virgolette quando si possono sottintendere. YAML supporta anche stringhe a più righe, che possono essere utili per le descrizioni lunghe.

Per configurare un'app per gestire il documento OpenAPI generato in formato YAML, specificare l'endpoint nella chiamata MapOpenApi con un suffisso ".yaml" o ".yml", come illustrato nell'esempio seguente:

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

Supporto per:

  • YAML è attualmente disponibile solo per OpenAPI servito dall'endpoint OpenAPI.
  • La generazione di documenti OpenAPI in formato YAML in fase di compilazione viene aggiunta in un'anteprima futura.

Consulta questa richiesta pull che ha aggiunto il supporto per servire il documento OpenAPI generato in formato YAML.

Descrizione della risposta in ProducesResponseType

Gli attributi ProducesAttribute, ProducesResponseTypeAttributee ProducesDefaultResponseType accettano ora un parametro stringa facoltativo, Description, che imposta la descrizione della risposta. Ecco un esempio:

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

E l'OpenAPI generato:

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

contributo comunitario di Sander ten Brinke🙏

Autenticazione e autorizzazione

In questa sezione vengono descritte le nuove funzionalità per l'autenticazione e l'autorizzazione.

Misto

Questa sezione descrive varie nuove funzionalità in ASP.NET Core 10.0.

Supporto migliore per i test delle app con istruzioni di primo livello

.NET 10 offre ora un supporto migliore per testare le app che usano istruzioni di primo livello. In precedenza gli sviluppatori dovevano aggiungere manualmente public partial class Program al file di Program.cs in modo che il progetto di test potesse fare riferimento al Program class. Il public partial class Program era necessario perché la funzionalità di istruzione di primo livello in C# 9 ha generato un Program class dichiarato come interno.

In .NET 10 viene usato un generatore di origine per generare la dichiarazione di public partial class Program se il programmatore non lo ha dichiarato in modo esplicito. Inoltre, è stato aggiunto un analizzatore per rilevare quando public partial class Program viene dichiarato in modo esplicito e consigliare allo sviluppatore di rimuoverlo.

immagine

Le seguenti richieste pull hanno contribuito a questa funzionalità:

Rilevare se l'URL è locale usando RedirectHttpResult.IsLocalUrl

Usare il nuovo metodo helper RedirectHttpResult.IsLocalUrl(url) per rilevare se un URL è locale. Un URL viene considerato locale se sono vere le condizioni seguenti:

Anche gli URL che usano percorsi virtuali"~/" sono locali.

IsLocalUrl è utile per convalidare gli URL prima di reindirizzarli per impedire attacchi di reindirizzamento aperti.

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

Grazie @martincostello per questo contributo!