Novità di Asp.net Core 9.0

Novità di Asp.net Core 9.0

ASP.NET Core 9.0 introduce diversi miglioramenti significativi che consentono agli sviluppatori di creare applicazioni Web più efficienti, sicure e flessibili. Questo articolo esplora alcune delle nuove funzionalità più importanti e le loro applicazioni pratiche, dimostrando come migliorano la capacità di creare prodotti migliori rispetto a .NET 8.

  1. HybridCache: un nuovo approccio alla memorizzazione nella cache
    HybridCache è una nuova libreria che unisce i vantaggi di IDistributedCache e IMemoryCache aggiungendo nuove capacità. Offre:

Protezione “Stampede” per impedire recuperi paralleli
Serializzazione configurabile
Un’API semplificata

Esempio:

public class WeatherService
{
    private readonly HybridCache _cache;

    public WeatherService(HybridCache cache)
    {
        _cache = cache;
    }

    public async Task<WeatherForecast> GetForecastAsync(string city, DateTime date, CancellationToken token = default)
    {
        return await _cache.GetOrCreateAsync(
            $"weather:{city}:{date:yyyyMMdd}",
            async cancel => await FetchWeatherDataAsync(city, date, cancel),
            token: token
        );
    }

    private async Task<WeatherForecast> FetchWeatherDataAsync(string city, DateTime date, CancellationToken token)
    {
        // Simulate an expensive API call
        await Task.Delay(2000, token);
        return new WeatherForecast { City = city, Date = date, Temperature = new Random().Next(-10, 35) };
    }
}

public class WeatherForecast
{
    public string City { get; set; }
    public DateTime Date { get; set; }
    public int Temperature { get; set; }
}

    privata asincrona Task<WeatherForecast> FetchWeatherDataAsync(string city, DateTime date, CancellationToken token)
    {
        // Simula una chiamata API costosa
        attendi Task.Delay(2000, token);
        restituisci nuovo WeatherForecast { Città = città, Data = data, Temperatura = nuovo Random().Next(-10, 35) };
    }
}

classe pubblica WeatherForecast
{
    stringa pubblica Città { ottieni; imposta; }
    pubblico DateTime Data { ottenere; impostare; }
    pubblico int Temperatura { get; set; }
}

Questo approccio semplifica notevolmente la logica di caching e riduce la complessità del codice. In .NET 8, ottenere una funzionalità simile richiedeva un’implementazione più complessa. IDistributedCache.

2. MapStaticAssets: ottimizzazione dei file statici – Novità di Asp.net Core 9.0

MapStaticAssets è un nuovo middleware che ottimizza automaticamente i file statici:

  • Esegue la compressione dei file (gzip e brotli)
  • Aggiunge ETag per un caching efficiente
  • L’ottimizzazione avviene in fase di compilazione e pubblicazione

Esempio:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();

app.MapStaticAssets();
// app.UseStaticFiles(); - This line is no longer needed

app.MapRazorPages();

app.Run();

Questa modifica riduce significativamente la dimensione dei file statici e ne accelera la distribuzione. Ad esempio, con la libreria MudBlazor, la dimensione del file è ridotta da 588,4 KB a 46,7 KB, una riduzione del 92,07%.

  1. Supporto di tipo polimorfico negli hub SignalR
    Gli hub SignalR ora supportano tipi polimorfici, consentendoci di ricevere una classe base e di gestire le sue classi derivate:
public class ChatHub : Hub
{
    public async Task SendMessage(ChatMessage message)
    {
        if (message is TextMessage textMessage)
        {
            await Clients.All.SendAsync("ReceiveTextMessage", textMessage.Sender, textMessage.Text);
        }
        else if (message is ImageMessage imageMessage)
        {
            await Clients.All.SendAsync("ReceiveImageMessage", imageMessage.Sender, imageMessage.ImageUrl);
        }
    }
}

[JsonPolymorphic]
[JsonDerivedType(typeof(TextMessage), nameof(TextMessage))]
[JsonDerivedType(typeof(ImageMessage), nameof(ImageMessage))]
public abstract class ChatMessage
{
    public string Sender { get; set; }
}

public class TextMessage : ChatMessage
{
    public string Text { get; set; }
}

public class ImageMessage : ChatMessage
{
    public string ImageUrl { get; set; }
}

Questa funzionalità ci consente di creare applicazioni in tempo reale più flessibili e scalabili.

  1. Supporto AOT nativo per SignalR
    ASP.NET Core 9.0 aggiunge il supporto di compilazione AOT nativo per SignalR, che aumenta le prestazioni dell’applicazione e riduce l’utilizzo della memoria. Ciò è particolarmente utile per i sistemi ad alto carico.

Esempio:

using Microsoft.AspNetCore.SignalR;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.AddSignalR();
builder.Services.Configure<JsonHubProtocolOptions>(o =>
{
    o.PayloadSerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

app.MapHub<ChatHub>("/chatHub");

app.Run();

[JsonSerializable(typeof(string))]
internal partial class AppJsonSerializerContext : JsonSerializerContext { }

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

  1. Generazione automatica della documentazione OpenAPI
    ASP.NET Core 9.0 offre supporto integrato per la generazione della documentazione OpenAPI:

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();
builder.Services.AddEndpointsApiExplorer();

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/weather/{city}", (string city) => 
    new WeatherForecast { City = city, Temperature = new Random().Next(-10, 35) })
    .WithName("GetWeatherForecast")
    .WithOpenApi();

app.Run();

public class WeatherForecast
{
    public string City { get; set; }
    public int Temperature { get; set; }
}

Questa funzionalità semplifica la creazione e la gestione della documentazione API, migliorando la produttività degli sviluppatori e l’usabilità delle API.

  1. Supporto per richieste di autorizzazione push (PAR) in OpenIdConnect
    L’aggiunta di PAR aumenta la sicurezza dei flussi OAuth e OIDC spostando i parametri di autorizzazione dal canale anteriore a quello posteriore. Ciò riduce i rischi di perdita e manipolazione dei dati.
builder.Services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddOpenIdConnect("oidc", oidcOptions =>
    {
        oidcOptions.Authority = "https://your-identity-provider.com";
        oidcOptions.ClientId = "your-client-id";
        oidcOptions.ClientSecret = "your-client-secret";
        oidcOptions.ResponseType = "code";
        oidcOptions.SaveTokens = true;

        // PAR is used automatically if the provider supports it
        // To disable:
        // oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Disable;
    });

Questo miglioramento è significativo per le applicazioni nei settori finanziario e sanitario, dove sono richiesti elevati standard di sicurezza.

Conclusione
Queste nuove funzionalità in ASP.NET Core 9.0 migliorano significativamente le capacità degli sviluppatori di creare applicazioni Web più efficienti, sicure e scalabili. Le ottimizzazioni di HybridCache e MapStaticAssets aumentano le prestazioni delle applicazioni, i miglioramenti di SignalR espandono le capacità di comunicazione in tempo reale, mentre l’integrazione di OpenAPI e PAR semplifica la gestione delle API e migliora la sicurezza. Queste modifiche ci consentiranno di creare prodotti di qualità superiore che soddisfano meglio le esigenze delle moderne applicazioni Web.

Esempio complesso: creazione di un dashboard meteo in tempo reale
Combiniamo alcune di queste nuove funzionalità per creare un’applicazione di dashboard meteo in tempo reale:

using Microsoft.AspNetCore.SignalR;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);

// Add services
builder.Services.AddSignalR();
builder.Services.AddHybridCache();
builder.Services.AddOpenApi();
builder.Services.AddEndpointsApiExplorer();

// Configure JSON options for SignalR
builder.Services.Configure<JsonHubProtocolOptions>(o =>
{
    o.PayloadSerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

// Configure the HTTP request pipeline
app.UseHttpsRedirection();
app.MapStaticAssets();

// Map SignalR hub
app.MapHub<WeatherHub>("/weatherHub");

// Map API endpoints
app.MapGet("/api/weather/{city}", async (string city, WeatherService weatherService) => 
    await weatherService.GetForecastAsync(city, DateTime.Now))
    .WithName("GetWeatherForecast")
    .WithOpenApi();

// Enable OpenAPI
app.MapOpenApi();

app.Run();

// Models and Services
public class WeatherForecast
{
    public string City { get; set; }
    public DateTime Date { get; set; }
    public int Temperature { get; set; }
    public string Condition { get; set; }
}

public class WeatherService
{
    private readonly HybridCache _cache;
    private readonly IHubContext<WeatherHub> _hubContext;

    public WeatherService(HybridCache cache, IHubContext<WeatherHub> hubContext)
    {
        _cache = cache;
        _hubContext = hubContext;
    }

    public async Task<WeatherForecast> GetForecastAsync(string city, DateTime date, CancellationToken token = default)
    {
        return await _cache.GetOrCreateAsync(
            $"weather:{city}:{date:yyyyMMdd}",
            async cancel => {
                var forecast = await FetchWeatherDataAsync(city, date, cancel);
                await _hubContext.Clients.All.SendAsync("ReceiveWeatherUpdate", forecast);
                return forecast;
            },
            token: token
        );
    }

    private async Task<WeatherForecast> FetchWeatherDataAsync(string city, DateTime date, CancellationToken token)
    {
        // Simulate an API call
        await Task.Delay(2000, token);
        return new WeatherForecast 
        { 
            City = city, 
            Date = date, 
            Temperature = new Random().Next(-10, 35),
            Condition = new[] { "Sunny", "Cloudy", "Rainy", "Snowy" }[new Random().Next(4)]
        };
    }
}

public class WeatherHub : Hub
{
    public async Task SubscribeToCity(string city)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, city);
    }
}

[JsonSerializable(typeof(WeatherForecast))]
[JsonSerializable(typeof(string))]
internal partial class AppJsonSerializerContext : JsonSerializerContext { }

Questo esempio dimostra:

  • Utilizzo di HybridCache per un’efficiente memorizzazione nella cache dei dati meteorologici.
  • MapStaticAssets Per ottimizzare la distribuzione di file statici.
  • SignalR con supporto AOT nativo per aggiornamenti in tempo reale.
  • Generazione della documentazione OpenAPI per l’endpoint API meteo.
  • Supporto di tipi polimorfici in SignalR (anche se non utilizzato esplicitamente, l’infrastruttura è presente).

Questa applicazione fornisce una dashboard meteo performante e in tempo reale con distribuzione ottimizzata di asset statici e caching efficiente. La documentazione OpenAPI semplifica l’integrazione con la nostra API meteo per altri sviluppatori. Rispetto a .NET 8, questa implementazione è più efficiente, più facile da gestire e fornisce esperienze migliori per sviluppatori e utenti fin da subito.

(fonte)

Innovaformazione, scuola informatica specialistica è costantemente aggiornata sui trend del mercato e promuove la formazione continua dei team di sviluppatori. Nell’offerta formativa per aziende trovate il Corso Asp .Net Core.

INFO: info@innovaformazione.net – tel. 3471012275 (Dario Carrassi).

Ti potrebbe interessare

Articoli correlati