Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra le modifiche più significative in ASP.NET Core in .NET 7 con collegamenti alla documentazione pertinente.
Middleware di limitazione della frequenza in ASP.NET Core
Il Microsoft.AspNetCore.RateLimiting middleware fornisce un middleware di limitazione del traffico. Le app configurano i criteri di limitazione della frequenza e quindi allegano i criteri agli endpoint. Per altre informazioni, vedere Middleware di limitazione della frequenza in ASP.NET Core.
L'autenticazione usa uno schema singolo come DefaultScheme
Come parte del lavoro per semplificare l'autenticazione, quando è registrato un solo schema di autenticazione, viene usato automaticamente come DefaultScheme e non deve essere specificato. Per altre informazioni, vedere DefaultScheme.
MVC e pagine Razor
Supporto per i modelli nullable nelle visualizzazioni MVC e Razor nelle pagine
I modelli di visualizzazione o pagina nullable sono supportati per migliorare l'esperienza quando si usa il controllo dello stato Null con le app ASP.NET Core:
@model Product?
Eseguire l'associazione con IParsable<T>.TryParse nei controller MVC e API
L'API IParsable<TSelf>.TryParse supporta l'associazione dei valori dei parametri di azione del controller. Per ulteriori informazioni, vedere Collegare con IParsable<T>.TryParse.
Personalizzare il valore di cookie consenso
In versioni precedenti alla 7 di ASP.NET Core, la cookie convalida del consenso usa il valore cookie per indicare il consenso yes. È ora possibile specificare il valore che rappresenta il consenso. Ad esempio, è possibile usare true invece di yes:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.ConsentCookieValue = "true";
});
var app = builder.Build();
Per altre informazioni, vedere Personalizzare il valore del consenso cookie.
controller di API
Associazione di parametri con inserimento di dipendenze nei controller API
L'associazione di parametri per le azioni del controller API avviene tramite l'iniezione delle dipendenze quando il tipo è configurato come servizio. Ciò significa che non è più necessario applicare in modo esplicito l'attributo [FromServices] a un parametro. Nel codice seguente entrambe le azioni restituiscono l'ora:
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
public ActionResult GetWithAttribute([FromServices] IDateTime dateTime)
=> Ok(dateTime.Now);
[Route("noAttribute")]
public ActionResult Get(IDateTime dateTime) => Ok(dateTime.Now);
}
In rari casi, l'inserimento automatico delle dipendenze può interrompere le app che hanno un tipo in DI che viene accettato anche in un metodo di azione del controller API. Non è comune avere un tipo in Injection delle Dipendenze e come argomento in un'azione di un controller API. Per disabilitare l'associazione automatica dei parametri, impostare DisableImplicitFromServicesParameters
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSingleton<IDateTime, SystemDateTime>();
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
options.DisableImplicitFromServicesParameters = true;
});
var app = builder.Build();
app.MapControllers();
app.Run();
In .NET 7, i tipi in DI vengono controllati all'avvio dell'app con IServiceProviderIsService per determinare se un argomento in un'azione del controller API proviene da DI o da altre fonti.
Il nuovo meccanismo per dedurre l'origine dell'associazione dei parametri di azione del controller API usa le regole seguenti:
- Un oggetto
BindingInfo.BindingSourcespecificato in precedenza non viene mai sovrascritto. - Un parametro di tipo complesso, registrato nel contenitore DI, viene assegnato
BindingSource.Services. - Viene assegnato
BindingSource.Bodyun parametro di tipo complesso, non registrato nel contenitore DI, . - A un parametro con un nome visualizzato come valore di route in qualsiasi modello di route viene assegnato
BindingSource.Path. - Tutti gli altri parametri sono
BindingSource.Query.
Nomi di proprietà JSON negli errori di convalida
Per impostazione predefinita, quando si verifica un errore di convalida, la convalida del modello produce un oggetto ModelStateDictionary con il nome della proprietà come chiave di errore. Alcune app, ad esempio le app a pagina singola, traggono vantaggio dall'uso dei nomi delle proprietà JSON per gli errori di convalida generati dalle API Web. Il codice seguente configura la convalida per l'uso di SystemTextJsonValidationMetadataProvider per usare i nomi delle proprietà JSON:
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.ModelMetadataDetailsProviders.Add(new SystemTextJsonValidationMetadataProvider());
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Il codice seguente configura la convalida per usare il nome della proprietà JSON quando si usa Json.NET:
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.ModelMetadataDetailsProviders.Add(new NewtonsoftJsonValidationMetadataProvider());
}).AddNewtonsoftJson();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Per altre informazioni, vedere Usare i nomi delle proprietà JSON negli errori di convalida
API minimali
Filtri nelle app per le API minime
I filtri API minimi consentono agli sviluppatori di implementare la logica di business che supporta:
- Esecuzione del codice prima e dopo il gestore di route.
- Controllo e modifica dei parametri forniti durante una chiamata del gestore di route.
- Intercettazione del comportamento della risposta di un gestore di routing.
I filtri possono essere utili negli scenari seguenti:
- Convalida dei parametri della richiesta e del corpo inviati a un endpoint.
- Registrazione delle informazioni sulla richiesta e sulla risposta.
- Convalidare che una richiesta sia destinata a una versione dell'API supportata.
Per altre informazioni, vedere Filtri nelle app per le API minime
Associare matrici e valori stringa da intestazioni e stringhe di query
In ASP.NET 7 è supportata l'associazione di stringhe di query a una matrice di tipi primitivi, matrici di stringhe e StringValues :
// Bind query string values to a primitive type array.
// GET /tags?q=1&q=2&q=3
app.MapGet("/tags", (int[] q) =>
$"tag1: {q[0]} , tag2: {q[1]}, tag3: {q[2]}");
// Bind to a string array.
// GET /tags2?names=john&names=jack&names=jane
app.MapGet("/tags2", (string[] names) =>
$"tag1: {names[0]} , tag2: {names[1]}, tag3: {names[2]}");
// Bind to StringValues.
// GET /tags3?names=john&names=jack&names=jane
app.MapGet("/tags3", (StringValues names) =>
$"tag1: {names[0]} , tag2: {names[1]}, tag3: {names[2]}");
L'associazione di stringhe di query o valori di intestazione a una matrice di tipi complessi è supportata quando il tipo è TryParse implementato. Per altre informazioni, vedere Associare array e valori stringa da intestazioni e stringhe di query.
Per altre informazioni, vedere Aggiungere il riepilogo o la descrizione dell'endpoint.
Associare il corpo della richiesta come Stream o PipeReader
Il corpo della richiesta può essere associato come un Stream o PipeReader per supportare in modo efficiente gli scenari in cui l'utente deve elaborare i dati e:
- Archiviare i dati nell'archivio BLOB o inserire i dati in una coda.
- Elaborare i dati archiviati con un processo di lavoro o una funzione cloud.
Ad esempio, i dati potrebbero essere accodati all'archiviazione di code di Azure o archiviati nell'archiviazione BLOB di Azure.
Per altre informazioni, vedere Associare il corpo della richiesta come Stream o PipeReader
Nuovi overloads di Results.Stream
Sono stati introdotti nuovi Results.Stream overloads per supportare scenari che richiedono l'accesso allo stream di risposta HTTP sottostante senza buffering. Questi overload migliorano anche i casi in cui un'API trasmette i dati nel flusso di risposta HTTP, ad esempio da Archiviazione BLOB di Azure. L'esempio seguente usa ImageSharp per restituire una dimensione ridotta dell'immagine specificata:
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/process-image/{strImage}", (string strImage, HttpContext http, CancellationToken token) =>
{
http.Response.Headers.CacheControl = $"public,max-age={TimeSpan.FromHours(24).TotalSeconds}";
return Results.Stream(stream => ResizeImageAsync(strImage, stream, token), "image/jpeg");
});
async Task ResizeImageAsync(string strImage, Stream stream, CancellationToken token)
{
var strPath = $"wwwroot/img/{strImage}";
using var image = await Image.LoadAsync(strPath, token);
int width = image.Width / 2;
int height = image.Height / 2;
image.Mutate(x =>x.Resize(width, height));
await image.SaveAsync(stream, JpegFormat.Instance, cancellationToken: token);
}
Per altre informazioni, vedere Esempi di flusso
Risultati tipizzati per le API minimali
In .NET 6 l'interfaccia IResult è stata introdotta per rappresentare i valori restituiti dalle API minime che non usano il supporto implicito per la serializzazione JSON dell'oggetto restituito alla risposta HTTP. La classe static Results viene usata per creare oggetti variabili IResult che rappresentano tipi diversi di risposte. Ad esempio, impostare il codice di stato della risposta o reindirizzare a un altro URL. I IResult tipi di framework di implementazione restituiti da questi metodi erano tuttavia interni, rendendo difficile verificare il tipo specifico IResult restituito dai metodi in uno unit test.
In .NET 7 i tipi che implementano IResult sono pubblici, consentendo le asserzioni di tipo durante il test. Per esempio:
[TestClass()]
public class WeatherApiTests
{
[TestMethod()]
public void MapWeatherApiTest()
{
var result = WeatherApi.GetAllWeathers();
Assert.IsInstanceOfType(result, typeof(Ok<WeatherForecast[]>));
}
}
Miglioramento della testabilità mediante unit test per i gestori di route minimi
IResult I tipi di implementazione sono ora pubblicamente disponibili nel namespace Microsoft.AspNetCore.Http.HttpResults. I IResult tipi di implementazione possono essere usati per unit test dei gestori di route minimi quando si usano metodi denominati anziché espressioni lambda.
Il codice seguente usa la Ok<TValue> classe :
[Fact]
public async Task GetTodoReturnsTodoFromDatabase()
{
// Arrange
await using var context = new MockDb().CreateDbContext();
context.Todos.Add(new Todo
{
Id = 1,
Title = "Test title",
Description = "Test description",
IsDone = false
});
await context.SaveChangesAsync();
// Act
var result = await TodoEndpointsV1.GetTodo(1, context);
//Assert
Assert.IsType<Results<Ok<Todo>, NotFound>>(result);
var okResult = (Ok<Todo>)result.Result;
Assert.NotNull(okResult.Value);
Assert.Equal(1, okResult.Value.Id);
}
Per altre informazioni, vedere IResult Tipi di implementazione.
Nuove interfacce HttpResult
Le interfacce seguenti nello spazio dei nomi Microsoft.AspNetCore.Http consentono di rilevare il tipo IResult in fase di esecuzione, un modello comune nelle implementazioni dei filtri:
- IContentTypeHttpResult
- IFileHttpResult
- INestedHttpResult
- IStatusCodeHttpResult
- IValueHttpResult
- IValueHttpResult<TValue>
Per altre informazioni, vedere Interfacce IHttpResult.
Miglioramenti di OpenAPI per le API minime
pacchetto NuGet Microsoft.AspNetCore.OpenApi
Il Microsoft.AspNetCore.OpenApi pacchetto consente interazioni con le specifiche OpenAPI per gli endpoint. Il pacchetto funge da collegamento tra i modelli OpenAPI definiti nel Microsoft.AspNetCore.OpenApi pacchetto e gli endpoint definiti nelle API minime. Il pacchetto fornisce un'API che esamina i parametri, le risposte e i metadati di un endpoint per costruire un tipo di annotazione OpenAPI usato per descrivere un endpoint.
app.MapPost("/todoitems/{id}", async (int id, Todo todo, TodoDb db) =>
{
todo.Id = id;
db.Todos.Add(todo);
await db.SaveChangesAsync();
return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi();
Chiamare WithOpenApi con parametri
Il WithOpenApi metodo accetta una funzione che può essere usata per modificare l'annotazione OpenAPI. Nel codice seguente, ad esempio, viene aggiunta una descrizione al primo parametro dell'endpoint:
app.MapPost("/todo2/{id}", async (int id, Todo todo, TodoDb db) =>
{
todo.Id = id;
db.Todos.Add(todo);
await db.SaveChangesAsync();
return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi(generatedOperation =>
{
var parameter = generatedOperation.Parameters[0];
parameter.Description = "The ID associated with the created Todo";
return generatedOperation;
});
Fornire descrizioni e riepiloghi degli endpoint
Le API minime supportano ora operazioni di annotazione con descrizioni e riepiloghi per la generazione di specifiche OpenAPI. È possibile chiamare i metodi di estensione WithDescription e WithSummary o usare gli attributi [EndpointDescription] e [EndpointSummary]).
Per altre informazioni, vedere OpenAPI nelle app per le API minime
Caricamenti di file con IFormFile e IFormFileCollection
Le API minime supportano ora il caricamento di file con IFormFile e IFormFileCollection. Il codice seguente usa IFormFile e IFormFileCollection per caricare il file:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapPost("/upload", async (IFormFile file) =>
{
var tempFile = Path.GetTempFileName();
app.Logger.LogInformation(tempFile);
using var stream = File.OpenWrite(tempFile);
await file.CopyToAsync(stream);
});
app.MapPost("/upload_many", async (IFormFileCollection myFiles) =>
{
foreach (var file in myFiles)
{
var tempFile = Path.GetTempFileName();
app.Logger.LogInformation(tempFile);
using var stream = File.OpenWrite(tempFile);
await file.CopyToAsync(stream);
}
});
app.Run();
Le richieste di caricamento di file autenticate sono supportate tramite un'intestazione di autorizzazione, un certificato client o un'intestazionecookie.
Non esiste alcun supporto predefinito per l'antifalsificazione. Tuttavia, può essere implementata usando il IAntiforgery servizio .
[AsParameters] attribute abilita l'associazione di parametri per gli elenchi di argomenti
L'attributo [AsParameters].
Controller API e API Minimale
Nuovo servizio dettagli problema
Il servizio dei dettagli del problema implementa l'interfaccia IProblemDetailsService, che supporta la creazione dei dettagli del problema per le API HTTP.
Per altre informazioni, vedere Servizio dettagli del problema.
Gruppi di instradamento
Il MapGroup metodo di estensione consente di organizzare gruppi di endpoint con un prefisso comune e riduce il codice ripetitivo. Usare questo metodo per personalizzare interi gruppi di endpoint con una singola chiamata a metodi come RequireAuthorization e WithMetadata che aggiungono metadati dell'endpoint.
Ad esempio, il codice seguente crea due gruppi simili di endpoint:
app.MapGroup("/public/todos")
.MapTodosApi()
.WithTags("Public");
app.MapGroup("/private/todos")
.MapTodosApi()
.WithTags("Private")
.AddEndpointFilterFactory(QueryPrivateTodos)
.RequireAuthorization();
EndpointFilterDelegate QueryPrivateTodos(EndpointFilterFactoryContext factoryContext, EndpointFilterDelegate next)
{
var dbContextIndex = -1;
foreach (var argument in factoryContext.MethodInfo.GetParameters())
{
if (argument.ParameterType == typeof(TodoDb))
{
dbContextIndex = argument.Position;
break;
}
}
// Skip filter if the method doesn't have a TodoDb parameter.
if (dbContextIndex < 0)
{
return next;
}
return async invocationContext =>
{
var dbContext = invocationContext.GetArgument<TodoDb>(dbContextIndex);
dbContext.IsPrivate = true;
try
{
return await next(invocationContext);
}
finally
{
// This should only be relevant if you're pooling or otherwise reusing the DbContext instance.
dbContext.IsPrivate = false;
}
};
}
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group)
{
group.MapGet("/", GetAllTodos);
group.MapGet("/{id}", GetTodo);
group.MapPost("/", CreateTodo);
group.MapPut("/{id}", UpdateTodo);
group.MapDelete("/{id}", DeleteTodo);
return group;
}
In questo scenario è possibile usare un indirizzo relativo per l'intestazione Location nel 201 Created risultato:
public static async Task<Created<Todo>> CreateTodo(Todo todo, TodoDb database)
{
await database.AddAsync(todo);
await database.SaveChangesAsync();
return TypedResults.Created($"{todo.Id}", todo);
}
Il primo gruppo di endpoint corrisponde solo alle richieste precedute da /public/todos e sono accessibili senza alcuna autenticazione. Il secondo gruppo di endpoint corrisponde solo alle richieste precedute da /private/todos e richiedono l'autenticazione.
QueryPrivateTodos è una funzione locale che modifica i TodoDb parametri del gestore di route per consentire loro di accedere e archiviare dati todo privati.
QueryPrivateTodos si comporta come una fabbrica di filtri endpoint.
I gruppi di route supportano anche gruppi annidati e modelli di prefisso complessi con parametri e vincoli di route. Nell'esempio seguente, il gestore di route mappato al user gruppo può acquisire i parametri di route {org} e {group} definiti nei prefissi dei gruppi esterni.
Il prefisso può anche essere vuoto. Questo approccio può essere utile per l'aggiunta di metadati o filtri dell'endpoint a un gruppo di endpoint senza modificare il modello di route.
var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");
L'aggiunta di filtri o metadati a un gruppo comporta lo stesso comportamento dell'aggiunta singolarmente a ogni endpoint (prima di aggiungere filtri o metadati aggiuntivi che potrebbero esistere in un gruppo interno o in un endpoint specifico).
var outer = app.MapGroup("/outer");
var inner = outer.MapGroup("/inner");
inner.AddEndpointFilter((context, next) =>
{
app.Logger.LogInformation("/inner group filter");
return next(context);
});
outer.AddEndpointFilter((context, next) =>
{
app.Logger.LogInformation("/outer group filter");
return next(context);
});
inner.MapGet("/", () => "Hi!").AddEndpointFilter((context, next) =>
{
app.Logger.LogInformation("MapGet filter");
return next(context);
});
Nell'esempio precedente il filtro esterno registra la richiesta in ingresso prima del filtro interno anche se il filtro esterno viene aggiunto secondo. Poiché i filtri vengono applicati a gruppi diversi, l'ordine in cui vengono aggiunti l'uno rispetto all'altro non è importante. L'ordine in cui vengono aggiunti i filtri è importante quando viene applicato allo stesso gruppo o allo stesso endpoint specifico.
Una richiesta a /outer/inner/ registra i seguenti dati:
/outer group filter
/inner group filter
MapGet filter
gRPC
Transcodifica JSON
La transcodifica JSON gRPC è un'estensione per ASP.NET Core che crea API JSON RESTful per i servizi gRPC. La transcodifica JSON gRPC consente di:
- App per chiamare i servizi gRPC con concetti HTTP familiari.
- ASP.NET app gRPC di base per supportare sia le API gRPC che LE API JSON RESTful senza replicare funzionalità.
- Supporto sperimentale per la generazione di OpenAPI da API RESTful transcodificate tramite l'integrazione con Swashbuckle.
Per ulteriori informazioni, vedere la transcodifica JSON di gRPC nelle app ASP.NET Core gRPC e Usare OpenAPI con la transcodifica JSON di gRPC nelle app ASP.NET Core.
Controlli di integrità gRPC in ASP.NET Core
Il protocollo di controllo dell'integrità gRPC è uno standard per segnalare l'integrità delle app server gRPC. Un'app espone i controlli di integrità come servizio gRPC. Vengono in genere usati con un servizio di monitoraggio esterno per controllare lo stato di un'app.
gRPC ASP.NET Core ha aggiunto il supporto predefinito per i controlli di integrità gRPC con il Grpc.AspNetCore.HealthChecks pacchetto. I risultati delle verifiche di salute .NET vengono segnalati ai chiamanti.
Per altre informazioni, vedere controlli di integrità gRPC in ASP.NET Core.
Supporto migliorato delle credenziali delle chiamate
Le credenziali di chiamata sono il modo consigliato per configurare un client gRPC per inviare un token di autenticazione al server. I client gRPC supportano due nuove funzionalità per semplificare l'uso delle credenziali delle chiamate:
- Supporto per le credenziali di chiamata con connessioni in testo non crittografato. In precedenza, una chiamata gRPC ha inviato credenziali di chiamata solo se la connessione è stata protetta con TLS. Una nuova impostazione su
GrpcChannelOptions, denominataUnsafeUseInsecureChannelCallCredentials, consente di personalizzare questo comportamento. Esistono implicazioni per la sicurezza per non proteggere una connessione con TLS. - È disponibile un nuovo metodo denominato
AddCallCredentialscon il client factory gRPC.AddCallCredentialsè un modo rapido per configurare le credenziali di chiamata per un client gRPC e si integra bene con l'iniezione di dipendenze.
Il codice seguente configura la factory client gRPC per l'invio Authorization di metadati:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials((context, metadata) =>
{
if (!string.IsNullOrEmpty(_token))
{
metadata.Add("Authorization", $"Bearer {_token}");
}
return Task.CompletedTask;
});
Per ulteriori informazioni, vedere Configurare un token di portatore con la factory client gRPC.
SignalR
Risultati del client
Il server supporta ora la richiesta di un risultato da un client. Ciò richiede che il server usi ISingleClientProxy.InvokeAsync e che il client restituisca un risultato dal relativo .On gestore. Gli hub fortemente tipizzati possono anche restituire valori dai metodi di interfaccia.
Per altre informazioni, vedere Risultati del client
Inserimento delle dipendenze nei metodi del hub SignalR
SignalR I metodi hub supportano ora l'inserimento di servizi tramite iniezione delle dipendenze.
I costruttori dell'hub possono accettare servizi di DI come parametri, che possono essere memorizzati nelle proprietà della classe da usare in un metodo dell'hub. Per altre informazioni, vedere Inserire i servizi in un hub
Blazor
Gestire gli eventi di cambio di ubicazione e lo stato di navigazione
In .NET 7 Blazor supporta la modifica della posizione degli eventi e la gestione dello stato di spostamento. In questo modo è possibile avvisare gli utenti del lavoro non salvato o di eseguire azioni correlate quando l'utente esegue una navigazione nella pagina.
Per altre informazioni, vedere le sezioni seguenti dell'articolo Routing e navigazione :
Modelli di progetto vuoti Blazor
Blazor ha due nuovi modelli di progetto per iniziare da un foglio bianco. I nuovi modelli di progetto Blazor Server App Empty e Blazor WebAssembly App Empty sono esattamente come le loro controparti non vuote, ma senza codice di esempio. Questi modelli vuoti includono solo una home page di base ed è stato rimosso Bootstrap in modo da poter iniziare con un framework CSS diverso.
Per altre informazioni, vedere gli articoli seguenti:
Blazor elementi personalizzati
Il Microsoft.AspNetCore.Components.CustomElements pacchetto abilita la compilazione di elementi DOM personalizzati basati su standard usando Blazor.
Per ulteriori informazioni, vedere i
Modificatori di binding (@bind:after, @bind:get, @bind:set)
Important
Le @bind:after/@bind:get/@bind:set funzionalità ricevono ulteriori aggiornamenti in questo momento. Per sfruttare i vantaggi degli aggiornamenti più recenti, verificare di aver installato l'SDK più recente.
L'uso di un parametro di callback di eventi ([Parameter] public EventCallback<string> ValueChanged { get; set; }) non è supportato. Invece, passa un metodo che restituisce Action o che restituisce Task a @bind:set/@bind:after.
Per ulteriori informazioni, vedi le seguenti risorse:
In .NET 7 è possibile eseguire la logica asincrona dopo il completamento di un evento di associazione usando il nuovo @bind:after modificatore. Nell'esempio seguente il PerformSearch metodo asincrono viene eseguito automaticamente dopo che sono state rilevate modifiche al testo di ricerca:
<input @bind="searchText" @bind:after="PerformSearch" />
@code {
private string searchText;
private async Task PerformSearch()
{
...
}
}
In .NET 7 è anche più semplice configurare l'associazione per i parametri del componente. I componenti possono supportare il data binding bidirezionale definendo una coppia di parametri:
-
@bind:get: specifica il valore da associare. -
@bind:set: specifica un callback per quando il valore cambia.
I @bind:get modificatori e @bind:set vengono sempre usati insieme.
Examples:
@* Elements *@
<input type="text" @bind="text" @bind:after="() => { }" />
<input type="text" @bind:get="text" @bind:set="(value) => { }" />
<input type="text" @bind="text" @bind:after="AfterAsync" />
<input type="text" @bind:get="text" @bind:set="SetAsync" />
<input type="text" @bind="text" @bind:after="() => { }" />
<input type="text" @bind:get="text" @bind:set="(value) => { }" />
<input type="text" @bind="text" @bind:after="AfterAsync" />
<input type="text" @bind:get="text" @bind:set="SetAsync" />
@* Components *@
<InputText @bind-Value="text" @bind-Value:after="() => { }" />
<InputText @bind-Value:get="text" @bind-Value:set="(value) => { }" />
<InputText @bind-Value="text" @bind-Value:after="AfterAsync" />
<InputText @bind-Value:get="text" @bind-Value:set="SetAsync" />
<InputText @bind-Value="text" @bind-Value:after="() => { }" />
<InputText @bind-Value:get="text" @bind-Value:set="(value) => { }" />
<InputText @bind-Value="text" @bind-Value:after="AfterAsync" />
<InputText @bind-Value:get="text" @bind-Value:set="SetAsync" />
@code {
private string text = "";
private void After(){}
private void Set() {}
private Task AfterAsync() { return Task.CompletedTask; }
private Task SetAsync(string value) { return Task.CompletedTask; }
}
Per ulteriori informazioni sul componente InputText, vedere componenti di input Blazor ASP.NET Core.
miglioramenti Ricaricamento rapido (Ricaricamento rapido)
In .NET 7, il supporto per Ricaricamento rapido include quanto segue:
- I componenti reimpostano i relativi parametri ai valori predefiniti quando viene rimosso un valore.
-
Blazor WebAssembly:
- Aggiungere nuovi tipi.
- Aggiungere classi annidate.
- Aggiungere metodi statici e di istanza ai tipi esistenti.
- Aggiungere campi e metodi statici ai tipi esistenti.
- Aggiungere espressioni lambda statiche ai metodi esistenti.
- Aggiungere espressioni lambda che acquisiscano
thisai metodi esistenti che in precedenza acquisivano giàthis.
Richieste di autenticazione dinamica con MSAL in Blazor WebAssembly
Novità di .NET 7 supporta Blazor WebAssembly la creazione di richieste di autenticazione dinamica in fase di esecuzione con parametri personalizzati per gestire scenari di autenticazione avanzati.
Per altre informazioni, vedere gli articoli seguenti:
- Secure ASP.NET Core Blazor WebAssembly
- Scenari di sicurezza aggiuntivi per ASP.NET Core Blazor WebAssembly
Blazor WebAssembly miglioramenti al debug
Blazor WebAssembly Il debug presenta i miglioramenti seguenti:
- Supporto per l'impostazione Just My Code per mostrare o nascondere i membri di tipo che non provengono dal codice utente.
- Supporto per l'ispezione di matrici multidimensionali.
- Stack di chiamate mostra ora il nome corretto per i metodi asincroni.
- Valutazione migliorata delle espressioni.
- Gestione corretta della
newparola chiave nei membri derivati. - Supporto per gli attributi correlati al debugger in
System.Diagnostics.
System.Security.Cryptography supporto per WebAssembly
.NET 6 supportava la famiglia SHA di algoritmi di hashing quando veniva eseguito su WebAssembly. .NET 7 consente un numero maggiore di algoritmi di crittografia sfruttando SubtleCrypto quando possibile, altrimenti ricorre a un'implementazione .NET qualora SubtleCrypto non possa essere usato. Gli algoritmi seguenti sono supportati in WebAssembly in .NET 7:
- SHA1
- SHA256
- SHA384
- SHA512
- HMACSHA1
- HMACSHA256
- HMACSHA384
- HMACSHA512
- AES-CBC
- PBKDF2
- HKDF
Per ulteriori informazioni, consultare gli sviluppatori che mirano a browser-wasm possono utilizzare le API Web Crypto (dotnet/runtime #40074).
Inserire i servizi negli attributi di convalida personalizzati
È ora possibile inserire i servizi negli attributi di convalida personalizzati.
Blazor imposta l'oggetto ValidationContext in modo che possa essere usato come provider di servizi.
Per ulteriori informazioni, consultare
Input* componenti esterni a un EditContext/EditForm
I componenti di input predefiniti sono ora supportati all'esterno di un modulo nel Razor markup dei componenti.
Per ulteriori informazioni, vedere ASP.NET Core Blazor componenti di input.
Modifiche al modello di progetto
Quando .NET 6 è stato rilasciato lo scorso anno, il markup HTML della pagina (_Host) è stato suddiviso tra la Pages/_Host.chstml pagina e una nuova _Host pagina (_Layout) nel modello di progetto .NET 6Pages/_Layout.chstml.Blazor Server
In .NET 7 il markup HTML è stato ricombinato con la _Host pagina nei modelli di progetto.
Sono state apportate diverse modifiche aggiuntive ai modelli di Blazor progetto. Non è possibile elencare tutte le modifiche apportate ai modelli nella documentazione. Per eseguire la migrazione di un'app a .NET 7 per adottare tutte le modifiche, vedere Eseguire la migrazione da ASP.NET Core in .NET 6 a .NET 7.
Componente sperimentale QuickGrid
Il nuovo componente QuickGrid offre un pratico componente griglia dati per i requisiti più comuni, e serve come architettura di riferimento e baseline delle prestazioni per chiunque sviluppi componenti della griglia dati Blazor.
Per ulteriori informazioni, consultare ASP.NET Core Blazor `QuickGrid` componente.
Dimostrazione dal vivo: QuickGrid per l'app di esempio Blazor
Miglioramenti della virtualizzazione
Miglioramenti della virtualizzazione in .NET 7:
- Il componente
Virtualizesupporta l'uso del documento stesso come radice di scorrimento, in alternativa al fatto di applicareoverflow-y: scrolla un altro elemento. - Se il
Virtualizecomponente viene inserito all'interno di un elemento che richiede un nome di tag figlio specifico,SpacerElementconsente di ottenere o impostare il nome del tag di spacer di virtualizzazione.
Per altre informazioni, vedere le sezioni seguenti dell'articolo Virtualizzazione :
MouseEventArgs Aggiornamenti
MovementX e MovementY sono stati aggiunti a MouseEventArgs.
Per ulteriori informazioni, vedere< c1 > gestione eventi ASP.NET Core< c0 />.
Nuova Blazor pagina di caricamento
Il Blazor WebAssembly modello di progetto ha una nuova interfaccia utente di caricamento che mostra lo stato di avanzamento del caricamento dell'app.
Per ulteriori informazioni, vedere
Diagnostica migliorata per l'autenticazione in Blazor WebAssembly
Per diagnosticare i problemi di autenticazione nelle Blazor WebAssembly app, è disponibile la registrazione dettagliata.
Per ulteriori informazioni, vedere registrazione dei log di ASP.NET CoreBlazor.
Interoperabilità JavaScript con WebAssembly
L'API di interoperabilità JavaScript [JSImport]/[JSExport] è un nuovo meccanismo di basso livello per l'uso di .NET nelle app basate su JavaScript. Con questa nuova funzionalità di interoperabilità JavaScript, è possibile richiamare il codice .NET da JavaScript usando il runtime .NET WebAssembly e chiamare la funzionalità JavaScript da .NET senza alcuna dipendenza dal modello del componente dell'interfaccia Blazor utente.
Per altre informazioni:
- Interoperabilità di JSImport/JSExport JavaScript con ASP.NET Core Blazor: si riferisce solo alle Blazor WebAssembly applicazioni.
- Interoperabilità JavaScript '[JSImport]'/'[JSExport]' in .NET WebAssembly: si riferisce solo alle app JavaScript che non dipendono dal modello di componenti dell'interfaccia utente.
Registrazione condizionale del provider di stato dell'autenticazione
Prima del rilascio di .NET 7, AuthenticationStateProvider è stato registrato nel contenitore del servizio con AddScoped. In questo modo è stato difficile eseguire il debug delle app, perché ha forzato un ordine specifico di registrazioni del servizio quando si fornisce un'implementazione personalizzata. A causa delle modifiche al framework interno nel tempo, non è più necessario eseguire la registrazione AuthenticationStateProvider con AddScoped.
Nel codice per sviluppatore apportare le modifiche seguenti alla registrazione del servizio del provider di stato di autenticazione:
- builder.Services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
+ builder.Services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
Nell'esempio precedente, ExternalAuthStateProvider è l'implementazione del servizio dello sviluppatore.
Miglioramenti agli strumenti di compilazione WebAssembly .NET
Nuove funzionalità del wasm-tools carico di lavoro per .NET 7 che consentono di migliorare le prestazioni e gestire le eccezioni:
- Supporto di WebAssembly Single Instruction, Multiple Data (SIMD) (solo con AOT, non supportato da Apple Safari)
- Supporto per la gestione delle eccezioni WebAssembly
Per ulteriori informazioni, vedere gli strumenti di build di ASP.NET Core Blazor WebAssembly e la compilazione ahead-of-time (AOT).
Blazor Hybrid
URL esterni
È stata aggiunta un'opzione che consente di aprire pagine Web esterne nel browser.
Per ulteriori informazioni, vedere ASP.NET Core Blazor Hybrid routing e navigazione.
Security
Sono disponibili nuove indicazioni per Blazor Hybrid gli scenari di sicurezza. Per altre informazioni, vedere gli articoli seguenti:
- Autenticazione e autorizzazione per ASP.NET Core Blazor Hybrid
- Considerazioni sulla sicurezza di ASP.NET Core Blazor Hybrid
Performance
Middleware di memorizzazione nella cache di output
La memorizzazione nella cache dell'output è un nuovo middleware che archivia le risposte di un'app Web e le fornisce da una cache invece di elaborarle ogni volta. La memorizzazione nella cache dell'output differisce dalla memorizzazione nella cache delle risposte nei modi seguenti:
- Il comportamento di memorizzazione nella cache è configurabile nel server.
- Le voci della cache possono essere invalidate a livello di codice.
- Il blocco delle risorse riduce il rischio di cache stampede e fulmine.
- La riconvalida della cache indica che il server può restituire un
304 Not Modifiedcodice di stato HTTP anziché un corpo della risposta memorizzato nella cache. - Il supporto di archiviazione della cache è estendibile.
Per altre informazioni, vedere Panoramica della memorizzazione nella cache e middleware di memorizzazione nella cache di output.
Miglioramenti di HTTP/3
Questa versione:
- Rende HTTP/3 completamente supportato da ASP.NET Core, non è più sperimentale.
- Migliora il supporto di Kestrel HTTP/3. Le due aree principali del miglioramento sono la parità delle funzionalità con HTTP/1.1 e HTTP/2 e le prestazioni.
- Fornisce supporto completo per UseHttps(ListenOptions, X509Certificate2) con HTTP/3. Kestreloffre opzioni avanzate per la configurazione dei certificati di connessione, ad esempio l'associazione all'indicazione del nome del server (SNI).
- Aggiunge il supporto per HTTP/3 in HTTP.sys e IIS.
L'esempio seguente illustra come usare un callback SNI per risolvere le opzioni TLS:
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(8080, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
var options = new SslServerAuthenticationOptions
{
ServerCertificate =
MyResolveCertForHost(context.ClientHelloInfo.ServerName)
};
return new ValueTask<SslServerAuthenticationOptions>(options);
},
});
});
});
Sono state eseguite operazioni significative in .NET 7 per ridurre le allocazioni HTTP/3. È possibile visualizzare alcuni di questi miglioramenti nelle pull request seguenti di GitHub:
- HTTP/3: Evitare allocazioni di token di annullamento per richiesta
- HTTP/3: Allocazioni ConnectionAbortedException da evitare
- HTTP/3: Pooling di ValueTask
Miglioramenti delle prestazioni HTTP/2
.NET 7 introduce una ri-architettura significativa del modo in cui Kestrel elabora le richieste HTTP/2. Le app ASP.NET Core con connessioni HTTP/2 occupate avranno una riduzione dell'utilizzo della CPU e un maggiore throughput.
In precedenza, l'implementazione del multiplexing HTTP/2 si basava su un blocco che controlla quale richiesta può scrivere nella connessione TCP sottostante. Una coda sicura per i thread sostituisce il blocco di scrittura. Ora, invece di litigare per quale thread ottiene il blocco di scrittura, le richieste ora si accodano e un processore dedicato le elabora. Le risorse cpu sprecate in precedenza sono disponibili per il resto dell'app.
Un luogo in cui questi miglioramenti possono essere notati è in gRPC, un framework RPC popolare che usa HTTP/2. Kestrel + benchmark gRPC mostrano un miglioramento significativo:
Le modifiche sono state apportate nel codice di scrittura di frame HTTP/2 che migliora le prestazioni quando sono presenti più flussi che tentano di scrivere dati in una singola connessione HTTP/2. Ora assegnamo il lavoro TLS al pool di thread e liberiamo più rapidamente un blocco di scrittura che altri flussi possono acquisire per scrivere i loro dati. La riduzione dei tempi di attesa può produrre miglioramenti significativi delle prestazioni nei casi in cui è presente una contesa per questo blocco di scrittura. Un benchmark gRPC con 70 flussi su una singola connessione (con TLS) ha mostrato un miglioramento del 15% delle richieste al secondo (RPS) con questa modifica.
Supporto di WebSocket Http/2
.NET 7 introduce il supporto webSocket su HTTP/2 per Kestrel, il SignalR client JavaScript e SignalR con Blazor WebAssembly.
L'uso di WebSocket su HTTP/2 sfrutta le nuove funzionalità, ad esempio:
- Compressione dell'intestazione.
- Multiplexing, che riduce il tempo e le risorse necessarie quando si effettuano più richieste al server.
Queste funzionalità supportate sono disponibili in Kestrel su tutte le piattaforme abilitate per HTTP/2. La negoziazione della versione è automatica nei browser e Kestrel, quindi non sono necessarie nuove API.
** Per ulteriori informazioni, vedere Supporto WebSocket HTTP/2.
Kestrel miglioramenti delle prestazioni nei computer con core elevati
Kestrel utilizza ConcurrentQueue<T> per molti scopi. Uno scopo è pianificare le operazioni di I/O nel trasporto Socket predefinito di Kestrel.
ConcurrentQueue Il partizionamento basato sul socket associato riduce la contesa e aumenta la velocità effettiva nei computer con molti core CPU.
La profilazione su macchine con core elevati su .NET 6 ha mostrato una significativa contesa in un'altra delle istanze ConcurrentQueue di Kestrel, che Kestrel utilizza per memorizzare nella cache i buffer di byte.
In .NET 7 il Kestrelpool di memoria viene partizionato allo stesso modo della coda di I/O, che comporta una contesa molto inferiore e una velocità effettiva più elevata nei computer con core elevati. Nelle 80 macchine virtuali ARM64 core si riscontra un miglioramento superiore al 500% delle risposte al secondo (RPS) nel benchmark techEmpower plaintext. Nelle macchine virtuali AMD core 48, il miglioramento è quasi del 100% nel benchmark JSON HTTPS.
ServerReady evento per misurare il tempo di avvio
Le app che usano EventSource possono misurare il tempo di avvio per comprendere e ottimizzare le prestazioni di avvio. Il nuovo evento ServerReady in Microsoft.AspNetCore.Hosting rappresenta il punto in cui il server è pronto per rispondere alle richieste.
Server
Nuovo evento ServerReady per misurare il tempo di avvio
L'evento ServerReady è stato aggiunto per misurare il tempo di avvio delle app ASP.NET Core.
Note
In genere, i collegamenti della documentazione alla sorgente di riferimento .NET caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, utilizzare il menu a tendina Seleziona rami o tag. Per ulteriori informazioni, vedere Come selezionare un tag di versione del codice sorgente di ASP.NET Core (dotnet/AspNetCore.Docs #26205).
IIS
Copia ombra in IIS
La copia ombra degli assembly dell'app nel Core Module (ANCM) di ASP.NET per IIS può offrire un'esperienza utente finale migliore rispetto all'arresto dell'app mediante la distribuzione di un file offline.
Per altre informazioni, vedere Copia ombra in IIS.
Miscellaneous
Kestrel miglioramenti completi della catena di certificati
HttpsConnectionAdapterOptions include una nuova proprietà ServerCertificateChain di tipo X509Certificate2Collection, che semplifica la convalida delle catene di certificati consentendo di specificare una catena completa, inclusi i certificati intermedi. Per altri dettagli, vedere dotnet/aspnetcore#21513 .
dotnet watch (strumento di monitoraggio per le applicazioni .NET)
Miglioramento dell'output della console per dotnet watch
L'output della console di dotnet Watch è stato migliorato per allinearsi meglio con la registrazione di ASP.NET Core e per distinguersi con 😮emojis😍.
Ecco un esempio dell'aspetto del nuovo output:
Per altre informazioni, vedere questa pull request di GitHub.
Configurare dotnet watch per riavviare sempre per le modifiche invasive
Le modifiche grossolane sono modifiche che non possono essere ricaricate dinamicamente. Per configurare dotnet watch per riavviare sempre senza richiedere modifiche intrusive, impostare la DOTNET_WATCH_RESTART_ON_RUDE_EDIT variabile di ambiente su true.
Modalità scura della pagina delle eccezioni per sviluppatori
Il supporto per la modalità scura è stato aggiunto alla pagina delle eccezioni dello sviluppatore, grazie a un contributo di Patrick Westerhoff. Per testare la modalità scura in un browser, dalla pagina degli strumenti di sviluppo impostare la modalità su scura. Ad esempio, in Firefox:
In Chrome:
Opzione modello di progetto per l'uso del metodo Program.Main invece delle istruzioni di primo livello
I modelli .NET 7 includono un'opzione per non usare istruzioni di primo livello e generare un namespace e un Main metodo dichiarato in una Program classe.
Usando l'interfaccia della riga di comando di .NET, usare l'opzione --use-program-main :
dotnet new web --use-program-main
Con Visual Studio, selezionare la nuova casella di controllo Non usare istruzioni di livello superiore durante la creazione del progetto:
Modelli di Angular e React aggiornati
Il modello di progetto Angular è stato aggiornato a Angular 14. Il modello di progetto React è stato aggiornato a React 18.2.
Gestire i token Web JSON in fase di sviluppo con dotnet user-jwts
Il nuovo dotnet user-jwts strumento da riga di comando può creare e gestire token WEB JSON locali specifici dell'app. Per altre informazioni, vedere Gestire token Web JSON in fase di sviluppo con dotnet user-jwts.
Supporto per intestazioni di richiesta aggiuntive in W3CLogger
È ora possibile specificare intestazioni di richiesta aggiuntive da registrare quando si usa il logger W3C chiamando AdditionalRequestHeaders() su W3CLoggerOptions:
services.AddW3CLogging(logging =>
{
logging.AdditionalRequestHeaders.Add("x-forwarded-for");
logging.AdditionalRequestHeaders.Add("x-client-ssl-protocol");
});
Per altre informazioni, vedere Opzioni W3CLogger.
Decompressione richiesta
Nuovo middleware di decompressione della richiesta:
- Consente agli endpoint API di accettare richieste con contenuto compresso.
- Usa l'intestazione
Content-EncodingHTTP per identificare e decomprimere automaticamente le richieste che contengono contenuto compresso. - Elimina la necessità di scrivere codice per gestire le richieste compresse.
Per altre informazioni, vedere Richiedere il middleware di decompressione.
Modifiche radicali
Usare gli articoli in Modifiche di rilievo in .NET per trovare modifiche di rilievo che potrebbero essere applicate durante l'aggiornamento di un'app a una versione più recente di .NET.