Modifiche che causano un'interruzione in .NET Core 3.0
Articolo
Se si esegue la migrazione alla versione 3.0 di .NET Core, ASP.NET Core o EF Core, le modifiche che causano un'interruzione elencate in questo articolo possono influire sull'app.
Per gestire meglio la superficie dell'API pubblica di ASP.NET Core, i tipi negli spazi dei nomi *.Internal (denominati API "pubternal") sono diventati per la maggior parte veramente interni. I membri di questi spazi dei nomi non erano concepiti per essere supportati come API pubbliche. Nelle versioni secondarie le API potevano bloccarsi e spesso lo hanno fatto. Il codice che dipende da queste API non funziona in modo corretto quando si esegue l'aggiornamento a ASP.NET Core 3.0.
Le API interessate sono contrassegnate con il modificatore di accesso public ed esistono negli spazi dei nomi *.Internal.
Nuovo comportamento
Le API interessate sono contrassegnate con il modificatore di accesso internal e non possono più essere usate dal codice all'esterno di tale assembly.
Motivo della modifica
Le indicazioni per queste API "pubternal" erano le seguenti:
Potevano essere modificate senza preavviso.
Non erano soggette a criteri .NET per evitare modifiche che causano un'interruzione.
Lasciare le API public (anche negli spazi dei nomi *.Internal) era fonte di creato confusione per i clienti.
Azione consigliata
Smettere di usare queste API "pubternal". In caso di domande sulle API da usare in alternativa, aprire un problema nel repository dotnet/aspnetcore.
Si consideri ad esempio il codice di buffering della richiesta HTTP seguente in un progetto ASP.NET Core 2.2. Il metodo di estensione EnableRewind esiste nello spazio dei nomi Microsoft.AspNetCore.Http.Internal.
HttpContext.Request.EnableRewind();
In un progetto ASP.NET Core 3.0 sostituire la chiamata EnableRewind con una chiamata al metodo di estensione EnableBuffering. La funzionalità di buffering della richiesta funziona come in passato. EnableBuffering chiama l'API che ora è internal.
HttpContext.Request.EnableBuffering();
Category
ASP.NET Core
API interessate
Tutte le API negli spazi dei nomi Microsoft.AspNetCore.* e Microsoft.Extensions.* che hanno un segmento Internal nel nome dello spazio dei nomi. Ad esempio:
Google ha iniziato a disattivare il sistema Accesso a Google+ per le app il 28 gennaio 2019.
Descrizione delle modifiche
ASP.NET 4.x e ASP.NET Core usavano le API di Accesso a Google+ per autenticare gli utenti degli account Google nelle app Web. I pacchetti NuGet interessati sono Microsoft.AspNetCore.Authentication.Google per ASP.NET Core e Microsoft.Owin.Security.Google per Microsoft.Owin con Web Forms ASP.NET e MVC.
Le API di sostituzione di Google usano un'origine dati e un formato differenti. Le mitigazioni e le soluzioni fornite di seguito tengono conto delle modifiche strutturali. Le app devono verificare che i dati continuino a soddisfare i requisiti. Ad esempio, nomi, indirizzi e-mail, collegamenti al profilo e foto del profilo possono fornire valori leggermente diversi rispetto a prima.
Versione introdotta
tutte le versioni. Questa modifica è esterna a ASP.NET Core.
Azione consigliata
Owin con Web Forms ASP.NET e MVC
Per Microsoft.Owin 3.1.0 e versioni successive, una mitigazione temporanea è illustrata qui. Le app devono completare i test con la mitigazione per rilevare le eventuali modifiche nel formato dei dati. È in programma il rilascio di Microsoft.Owin 4.0.1 con un aggiornamento. Le app che usano qualsiasi versione precedente devono essere aggiornate alla versione 4.0.1.
Per Microsoft.AspNetCore.Authentication.Google versione 2.x, sostituire la chiamata esistente a AddGoogle in Startup.ConfigureServices con il codice seguente:
Le patch di febbraio delle versioni 2.1 e 2.2 incorporavano la riconfigurazione precedente come nuova impostazione predefinita. Non è prevista alcuna patch per ASP.NET Core 2.0 perché ha raggiunto la fine del ciclo di vita.
ASP.NET Core 3.0
La mitigazione fornita per ASP.NET Core 2.x può essere usata anche per ASP.NET Core 3.0. Nelle prossime anteprime della versione 3.0, il pacchetto Microsoft.AspNetCore.Authentication.Google potrebbe essere rimosso. Gli utenti verrebbero reindirizzati a Microsoft.AspNetCore.Authentication.OpenIdConnect. Il codice seguente mostra come sostituire AddGoogle con AddOpenIdConnect in Startup.ConfigureServices. Questa sostituzione può essere usata con ASP.NET Core 2.0 e versioni successive e può essere adattata per ASP.NET Core 1.x in base alle esigenze.
.AddOpenIdConnect("Google", o =>
{
o.ClientId = Configuration["Authentication:Google:ClientId"];
o.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
o.Authority = "https://accounts.google.com";
o.ResponseType = OpenIdConnectResponseType.Code;
o.CallbackPath = "/signin-google"; // Or register the default "/signin-oidc"
o.Scope.Add("email");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
Autenticazione: proprietà HttpContext.Authentication rimossa
La proprietà deprecata Authentication in HttpContext è stata rimossa.
Descrizione delle modifiche
Come parte di dotnet/aspnetcore#6504, la proprietà deprecata Authentication in HttpContext è stata rimossa. La proprietà Authentication è stata deprecata a partire dalla versione 2.0. È stata pubblicata una guida alla migrazione per eseguire la migrazione del codice che usa questa proprietà deprecata alle nuove API sostitutive. Le rimanenti classi/API inutilizzate correlate al vecchio stack di autenticazione ASP.NET Core 1.x sono state rimosse nel commit dotnet/aspnetcore@d7a7c65.
In ASP.NET Core 3.0, i tipi Newtonsoft.Json usati nelle API di autenticazione sono stati sostituiti con tipi System.Text.Json. Tranne che nei casi seguenti, l'utilizzo di base dei pacchetti di autenticazione rimane invariato:
Classi derivate da provider OAuth, ad esempio quelle di aspnet-contrib.
Implementazioni avanzate di manipolazione delle attestazioni.
Per le implementazioni OAuth derivate, la modifica più comune consiste nel sostituire JObject.Parse con JsonDocument.Parse nell'override CreateTicketAsync, come illustrato qui. JsonDocument implementa IDisposable.
L'elenco seguente illustra le modifiche note:
ClaimAction.Run(JObject, ClaimsIdentity, String) diventa ClaimAction.Run(JsonElement userData, ClaimsIdentity identity, string issuer). Lo stesso si verifica per tutte le implementazioni derivate di ClaimAction.
In OAuthCreatingTicketContext è stato rimosso un costruttore precedente e nell'altro è stato sostituito JObject con JsonElement. La proprietà User e il metodo RunClaimActions sono stati aggiornati in modo che corrispondano.
Success(JObject) ora accetta un parametro di tipo JsonDocument anziché JObject. La Response proprietà è stata aggiornata in modo che corrisponda. OAuthTokenResponse ora è eliminabile e verrà eliminato da OAuthHandler. Le implementazioni OAuth derivate che eseguono l'override di ExchangeCodeAsync non devono necessariamente eliminare JsonDocument o OAuthTokenResponse.
Le stringhe code e redirectUri venivano passate come argomenti separati.
Nuovo comportamento
Code e RedirectUri sono proprietà di OAuthCodeExchangeContext che è possibile impostare tramite il costruttore OAuthCodeExchangeContext. Il nuovo tipo di OAuthCodeExchangeContext è l'unico argomento passato a OAuthHandler.ExchangeCodeAsync.
Motivo della modifica
Questa modifica consente di specificare parametri aggiuntivi senza causare interruzioni. Non è necessario creare nuovi overload di ExchangeCodeAsync.
Azione consigliata
Costruire un elemento OAuthCodeExchangeContext con i valori code e redirectUri appropriati. È necessario specificare un'istanza di AuthenticationProperties. È possibile passare a OAuthHandler.ExchangeCodeAsync questa singola istanza di OAuthCodeExchangeContext anziché più argomenti.
Autorizzazione: overload di AddAuthorization spostato in un assembly diverso
I metodi principali AddAuthorization presenti in genere in Microsoft.AspNetCore.Authorization sono stati rinominati in AddAuthorizationCore. I metodi AddAuthorization precedenti esistono ancora, ma si trovano nell'assembly Microsoft.AspNetCore.Authorization.Policy. Le app che usano entrambi i metodi non dovrebbero subire conseguenze. Si noti che Microsoft.AspNetCore.Authorization.Policy ora viene fornito nel framework condiviso anziché in un pacchetto autonomo, come descritto in Framework condiviso: assembly rimossi da Microsoft.AspNetCore.App.
Versione introdotta
3,0
Comportamento precedente
I metodi AddAuthorization esistevano in Microsoft.AspNetCore.Authorization.
Nuovo comportamento
I metodi AddAuthorization esistono in Microsoft.AspNetCore.Authorization.Policy. AddAuthorizationCore è il nuovo nome dei metodi precedenti.
Motivo della modifica
AddAuthorization è un nome di metodo migliore per l'aggiunta di tutti i servizi comuni necessari per l'autorizzazione.
Azione consigliata
Aggiungere un riferimento a Microsoft.AspNetCore.Authorization.Policy o usare AddAuthorizationCore.
Autorizzazione: IAllowAnonymous rimosso da AuthorizationFilterContext.Filters
A partire da ASP.NET Core 3.0, MVC non aggiunge AllowAnonymousFilters per gli attributi [AllowAnonymous] individuati nei controller e nei metodi di azione. Questa modifica viene risolta in locale per i derivati di AuthorizeAttribute, ma si tratta di una modifica che causa un'interruzione per le implementazioni di IAsyncAuthorizationFilter e IAuthorizationFilter. Tali implementazioni, incapsulate in un attributo [TypeFilter] sono un modo diffuso e supportato per ottenere un'autorizzazione basata su attributi fortemente tipizzati quando sono necessari sia la configurazione che l'inserimento delle dipendenze.
Versione introdotta
3,0
Comportamento precedente
IAllowAnonymous compariva nella raccolta AuthorizationFilterContext.Filters. Testare la presenza dell'interfaccia era un approccio valido per eseguire l'override o disabilitare il filtro su singoli metodi del controller.
Nuovo comportamento
IAllowAnonymous non compare più nella raccolta AuthorizationFilterContext.Filters. Le implementazioni di IAsyncAuthorizationFilter dipendenti dal comportamento precedente causano a intermittenza risposte HTTP 401 (accesso non autorizzato) o HTTP 403 (accesso negato).
Motivo della modifica
In ASP.NET Core 3.0 è stata introdotta una nuova strategia di routing degli endpoint.
Azione consigliata
Cercare i metadati dell'endpoint per IAllowAnonymous. Ad esempio:
var endpoint = context.HttpContext.GetEndpoint();
if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
{
}
Autorizzazione: le implementazioni di IAuthorizationPolicyProvider richiedono un nuovo metodo
In ASP.NET Core 3.0, un nuovo metodo GetFallbackPolicyAsync è stato aggiunto a IAuthorizationPolicyProvider. Questo criterio di fallback viene usato dal middleware di autorizzazione quando non è specificato alcun criterio.
Era disponibile la proprietà MemoryCacheOptions.CompactOnMemoryPressure.
Nuovo comportamento
La proprietà MemoryCacheOptions.CompactOnMemoryPressure è stata rimossa.
Motivo della modifica
La compattazione automatica della cache provocava problemi. Per evitare comportamenti imprevisti, la cache deve essere compattata solo quando è necessario.
Azione consigliata
Per compattare la cache, eseguire il downcast a MemoryCache e chiamare Compact quando necessario.
Memorizzazione nella cache: Microsoft.Extensions.Caching.SqlServer usa un nuovo pacchetto SqlClient
Il pacchetto Microsoft.Extensions.Caching.SqlServer userà il nuovo pacchetto Microsoft.Data.SqlClient anziché il pacchetto System.Data.SqlClient. Questa modifica potrebbe causare modifiche che causano un'interruzione di lieve entità. Per altre informazioni, vedere la presentazione del nuovo Microsoft.Data.SqlClient.
Versione introdotta
3,0
Comportamento precedente
Il pacchetto Microsoft.Extensions.Caching.SqlServer usava il pacchetto System.Data.SqlClient.
Nuovo comportamento
Ora Microsoft.Extensions.Caching.SqlServer usa il pacchetto Microsoft.Data.SqlClient.
Motivo della modifica
Microsoft.Data.SqlClient è un nuovo pacchetto basato su System.Data.SqlClient. È qui che da ora in poi verrà svolto tutto il lavoro delle nuove funzionalità.
Azione consigliata
I clienti non devono preoccuparsi di questa modifica che causa un'interruzione, a meno che non usino tipi restituiti dal pacchetto Microsoft.Extensions.Caching.SqlServer e ne eseguano il cast a tipi System.Data.SqlClient. Ad esempio, se si eseguiva il cast di un elemento DbConnection al vecchio tipo SqlConnection, è necessario modificare il cast nel nuovo tipo Microsoft.Data.SqlClient.SqlConnection.
Category
ASP.NET Core
API interessate
None
Memorizzazione nella cache: tipi "pubternal" di ResponseCaching modificati in tipi interni
In ASP.NET Core 3.0 i tipi "pubternal" in ResponseCaching sono stati modificati in internal.
Inoltre, le implementazioni predefinite di IResponseCachingPolicyProvider e IResponseCachingKeyProvider non vengono più aggiunte ai servizi come parte del metodo AddResponseCaching.
Descrizione delle modifiche
In ASP.NET Core i tipi "pubternal" vengono dichiarati come public, ma risiedono in uno spazio dei nomi con il suffisso .Internal. Sebbene questi tipi siano pubblici, non hanno criteri di supporto e sono soggetti a modifiche che causano un'interruzione. Sfortunatamente, l'uso accidentale di questi tipi è stato frequente, dando luogo a modifiche che causano interruzioni in questi progetti e limitando la capacità di gestire il framework.
Versione introdotta
3,0
Comportamento precedente
Questi tipi erano visibili pubblicamente, ma non supportati.
Nuovo comportamento
Ora questi tipi sono internal.
Motivo della modifica
L'ambito internal è più idoneo per l'assenza di criteri di supporto.
Azione consigliata
Copiare i tipi usati dalla propria app o libreria.
Protezione dei dati: DataProtection.Blobs usa nuove API di Archiviazione di Azure
Azure.Extensions.AspNetCore.DataProtection.Blobs dipende dalle librerie di Archiviazione di Azure. In queste librerie sono stati rinominati gli assembly, i pacchetti e gli spazi dei nomi. A partire da ASP.NET Core 3.0, Azure.Extensions.AspNetCore.DataProtection.Blobs usa i nuovi pacchetti e le nuove API con prefisso Azure.Storage..
Il pacchetto faceva riferimento al pacchetto NuGet WindowsAzure.Storage.
Il pacchetto fa riferimento al pacchetto NuGet Microsoft.Azure.Storage.Blob.
Nuovo comportamento
Il pacchetto fa riferimento al pacchetto NuGet Azure.Storage.Blob.
Motivo della modifica
Questa modifica consente a Azure.Extensions.AspNetCore.DataProtection.Blobs di eseguire la migrazione ai pacchetti di Archiviazione di Azure consigliati.
Azione consigliata
Se è ancora necessario usare le API di Archiviazione di Azure precedenti con ASP.NET Core 3.0, aggiungere una dipendenza diretta al pacchetto WindowsAzure.Storage o Microsoft.Azure.Storage. Questo pacchetto può essere installato insieme alle nuove API Azure.Storage.
In molti casi, l'aggiornamento implica solo la modifica delle istruzioni using in modo da usare i nuovi spazi dei nomi:
- using Microsoft.WindowsAzure.Storage;
- using Microsoft.WindowsAzure.Storage.Blob;
- using Microsoft.Azure.Storage;
- using Microsoft.Azure.Storage.Blob;
+ using Azure.Storage;
+ using Azure.Storage.Blobs;
Category
ASP.NET Core
API interessate
None
Hosting: AspNetCoreModule V1 rimosso dal bundle di hosting Windows
A partire da ASP.NET Core 3.0, il bundle di hosting Windows non conterrà AspNetCoreModule (ANCM) V1.
ANCM V2 è compatibile con le versioni precedenti di ANCM OutOfProcess ed è consigliato per l'uso con le app ASP.NET Core 3.0.
ANCM V1 non è incluso nel bundle di hosting Windows.
Motivo della modifica
ANCM V2 è compatibile con le versioni precedenti di ANCM OutOfProcess ed è consigliato per l'uso con le app ASP.NET Core 3.0.
Azione consigliata
Usare ANCM V2 con le app ASP.NET Core 3.0.
Se è necessario ANCM V1, può essere installato usando il bundle di hosting Windows per ASP.NET Core 2.1 o 2.2.
Questa modifica interromperà il funzionamento delle app ASP.NET Core 3.0 che:
Hanno acconsentito esplicitamente all'uso di ANCM V1 con <AspNetCoreModuleName>AspNetCoreModule</AspNetCoreModuleName>.
Hanno un file web.config personalizzato con <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />.
Category
ASP.NET Core
API interessate
None
Hosting: l'host generico limita l'inserimento del costruttore Startup
Gli unici tipi supportati dall'host generico per l'inserimento del costruttore di classe Startup sono IHostEnvironment, IWebHostEnvironment e IConfiguration. Le app che usano WebHost non sono interessate.
Descrizione delle modifiche
Prima di ASP.NET Core 3.0, era possibile usare l'inserimento del costruttore per i tipi arbitrari nel costruttore della classe Startup. In ASP.NET Core 3.0, lo stack Web è stato migrato alla libreria host generica. La modifica è visibile nel file Program.cs dei modelli:
Host usa un contenitore di inserimento delle dipendenze (DI) per compilare l'app. WebHost usa due contenitori, uno per l'host e uno per l'app. Di conseguenza, il costruttore Startup non supporta più l'inserimento di servizi personalizzati. È possibile inserire solo IHostEnvironment, IWebHostEnvironment e IConfiguration. Questa modifica evita i problemi di inserimento delle dipendenze, ad esempio la creazione duplicata di un servizio singleton.
Versione introdotta
3,0
Motivo della modifica
Questa modifica è una conseguenza della conversione della piattaforma dello stack Web nella libreria host generica.
Azione consigliata
Inserire i servizi nella firma del metodo Startup.Configure. Ad esempio:
public void Configure(IApplicationBuilder app, IOptions<MyOptions> options)
Category
ASP.NET Core
API interessate
None
Hosting: reindirizzamento HTTPS abilitato per le app IIS out-of-process
La versione 13.0.19218.0 del modulo ASP.NET Core (ANCM) per l'hosting tramite IIS out-of-process abilita una funzionalità di reindirizzamento HTTPS esistente per le app ASP.NET Core 3.0 e 2.2.
Il modello di progetto ASP.NET Core 2.1 ha introdotto per la prima volta il supporto per i metodi middleware HTTPS come UseHttpsRedirection e UseHsts. Per abilitare il reindirizzamento HTTPS era necessaria l'aggiunta della configurazione, poiché le app in fase di sviluppo non usano la porta predefinita 443. HTTP Strict Transport Security (HSTS) è attivo solo se la richiesta usa già HTTPS. Localhost viene ignorato per impostazione predefinita.
Nuovo comportamento
In ASP.NET Core 3.0, lo scenario HTTPS di IIS è stato migliorato. Con il miglioramento, un'app poteva individuare le porte HTTPS del server e far funzionare UseHttpsRedirection per impostazione predefinita. Il componente in-process eseguiva l'individuazione delle porte con la funzionalità IServerAddresses; questo influisce solo sulle app ASP.NET Core 3.0 perché la libreria in-process ha la stessa versione del framework. Il componente out-of-process è stato modificato in modo da aggiungere automaticamente la variabile di ambiente ASPNETCORE_HTTPS_PORT. Questa modifica aveva effetto sulle app ASP.NET Core 2.2 e 3.0, perché il componente out-of-process è condiviso a livello globale. Le app ASP.NET Core 2.1 non sono interessate perché usano una versione precedente di ANCM per impostazione predefinita.
In ASP.NET Core 3.0.1 e 3.1.0 Preview 3 il comportamento precedente è stato modificato in modo da annullare le modifiche funzionali apportate in ASP.NET Core 2.x. Queste modifiche influiscono solo sulle app IIS out-of-process.
Come descritto in precedenza, l'installazione di ASP.NET Core 3.0.0 aveva come effetto collaterale anche l'attivazione del middleware UseHttpsRedirection nelle app ASP.NET Core 2.x. In ASP.NET Core 3.0.1 e 3.1.0 Preview 3 è stata apportata una modifica ad ANCM in modo che l'installazione non abbia più questo effetto sulle app ASP.NET Core 2.x. La variabile di ambiente ASPNETCORE_HTTPS_PORT popolata da ANCM in ASP.NET Core 3.0.0 è stata modificata in ASPNETCORE_ANCM_HTTPS_PORT nelle versioni ASP.NET Core 3.0.1 e 3.1.0 Preview 3. In queste versioni è stato aggiornato anche UseHttpsRedirection per comprendere sia le nuove variabili che quelle precedenti. ASP.NET Core 2.x non verrà aggiornato. Di conseguenza, ripristina il comportamento precedente di essere disabilitato per impostazione predefinita.
Motivo della modifica
Miglioramento della funzionalità di ASP.NET Core 3.0.
Azione consigliata
Se si vuole che tutti i client usino HTTPS, non è necessario alcun intervento. Per consentire ad alcuni client di usare HTTP, eseguire una delle operazioni seguenti:
Rimuovere le chiamate a UseHttpsRedirection e UseHsts dal metodo Startup.Configure del progetto e ridistribuire l'app.
Nel file web.config impostare la variabile di ambiente ASPNETCORE_HTTPS_PORT su una stringa vuota. Questa modifica può essere apportata direttamente nel server senza ridistribuire l'app. Ad esempio:
Attivato manualmente in ASP.NET Core 2.x impostando la variabile di ambiente ASPNETCORE_HTTPS_PORT sul numero di porta appropriato, che nella maggior parte degli scenari di produzione è 443.
Disattivato in ASP.NET Core 3.x definendo ASPNETCORE_ANCM_HTTPS_PORT con un valore stringa vuoto. Questo valore si imposta nello stesso modo dell'esempio ASPNETCORE_HTTPS_PORT precedente.
I computer che eseguono app ASP.NET Core 3.0.0 devono installare il runtime ASP.NET Core 3.0.1 prima di installare il modulo ANCM di ASP.NET Core 3.1.0 Preview 3. Questo garantisce che UseHttpsRedirection continui a funzionare come previsto per le app ASP.NET Core 3.0.
In Servizio app di Azure, ANCM viene distribuito separatamente rispetto al runtime a causa della sua natura globale. ANCM è stato distribuito in Azure con queste modifiche dopo la distribuzione di ASP.NET Core 3.0.1 e 3.1.0.
Hosting: tipi IHostingEnvironment e IApplicationLifetime sostituiti
Sono stati introdotti nuovi tipi per sostituire i tipi IHostingEnvironment e IApplicationLifetime esistenti.
Versione introdotta
3,0
Comportamento precedente
Esistevano due tipi IHostingEnvironment e IApplicationLifetime diversi provenienti da Microsoft.Extensions.Hosting e Microsoft.AspNetCore.Hosting.
Nuovo comportamento
I tipi precedenti sono stati contrassegnati come obsoleti e sostituiti con nuovi tipi.
Motivo della modifica
Quando Microsoft.Extensions.Hosting è stato introdotto in ASP.NET Core 2.1, alcuni tipi come IHostingEnvironment e IApplicationLifetime sono stati copiati da Microsoft.AspNetCore.Hosting. A seguito di alcune modifiche di ASP.NET Core 3.0, le app includono entrambi gli spazi dei nomi Microsoft.Extensions.Hosting e Microsoft.AspNetCore.Hosting. Qualsiasi uso di questi tipi duplicati causa un errore del compilatore "riferimento ambiguo" quando viene fatto riferimento a entrambi gli spazi dei nomi.
Azione consigliata
Sostituire tutti gli utilizzi dei tipi precedenti con i nuovi tipi introdotti, come indicato di seguito:
I nuovi metodi di estensione IHostEnvironmentIsDevelopment e IsProduction si trovano nello spazio dei nomi Microsoft.Extensions.Hosting. Può essere necessario aggiungere tale spazio dei nomi al progetto.
Hosting: ObjectPoolProvider rimosso dalle dipendenze di WebHostBuilder
Per rendere ASP.NET Core più efficiente, ObjectPoolProvider è stato rimosso dal set di dipendenze principale. Ora gli specifici componenti che si basano su ObjectPoolProvider vengono aggiunti automaticamente.
WebHostBuilder fornisce ObjectPoolProvider per impostazione predefinita nel contenitore di inserimento delle dipendenze.
Nuovo comportamento
WebHostBuilder non fornisce più ObjectPoolProvider per impostazione predefinita nel contenitore di inserimento delle dipendenze.
Motivo della modifica
Questa modifica è stata apportata per rendere ASP.NET Core più efficiente.
Azione consigliata
Se il componente richiede ObjectPoolProvider, va aggiunto alle dipendenze tramite IServiceCollection.
Category
ASP.NET Core
API interessate
None
HTTP: estendibilità di DefaultHttpContext rimossa
Nell'ambito dei miglioramenti delle prestazioni di ASP.NET Core 3.0, l'estendibilità di DefaultHttpContext è stata rimossa. La classe è ora sealed. Per altre informazioni, vedere dotnet/aspnetcore#6504.
Se gli unit test usano Mock<DefaultHttpContext>, usare Mock<HttpContext> o new DefaultHttpContext().
Le classi non possono derivare da DefaultHttpContext.
Motivo della modifica
Inizialmente, l'estendibilità è stata fornita per consentire il pooling di HttpContext, ma ha introdotto una complessità non necessaria e ha impedito altre ottimizzazioni.
Azione consigliata
Se si usa Mock<DefaultHttpContext> negli unit test, iniziare a usare Mock<HttpContext>.
HTTP: modifiche all'infrastruttura del corpo della risposta
L'infrastruttura che supporta il corpo della risposta HTTP è stata modificata. Se si usa HttpResponse direttamente, non è necessario apportare modifiche al codice. Continuare a leggere se si esegue il wrapping o la sostituzione di HttpResponse.Body o si accede a HttpContext.Features.
Versione introdotta
3,0
Comportamento precedente
Al corpo della risposta HTTP erano associate tre API:
IHttpResponseFeature.Body
IHttpSendFileFeature.SendFileAsync
IHttpBufferingFeature.DisableResponseBuffering
Nuovo comportamento
Se si sostituisce HttpResponse.Body, sostituisce l'intera interfaccia IHttpResponseBodyFeature con un wrapper intorno al flusso specificato, usando StreamResponseBodyFeature per fornire implementazioni predefinite per tutte le API previste. Il ripristino del flusso originale annulla questa modifica.
Motivo della modifica
La motivazione è combinare le API del corpo della risposta in un'unica nuova interfaccia di funzionalità.
Azione consigliata
Usare IHttpResponseBodyFeature dove in precedenza si usava IHttpResponseFeature.Body, IHttpSendFileFeature o IHttpBufferingFeature.
HTTP: alcuni valori predefiniti SameSite per i cookie sono stati modificati in None
SameSite è un'opzione per i cookie utile per mitigare alcuni attacchi di richiesta intersito falsa. Quando questa opzione è stata introdotta per la prima volta, nelle varie API ASP.NET Core sono state usate impostazioni predefinite incoerenti. Questa incoerenza ha generato risultati confusi. A partire da ASP.NET Core 3.0, queste impostazioni predefinite sono più allineate. È necessario acconsentire esplicitamente a questa funzionalità per ogni singolo componente.
Versione introdotta
3,0
Comportamento precedente
API ASP.NET Core simili usavano valori predefiniti di SameSiteMode diversi. Un esempio di questa incoerenza compare in HttpResponse.Cookies.Append(String, String) e HttpResponse.Cookies.Append(String, String, CookieOptions), che usavano rispettivamente i valori predefiniti SameSiteMode.None e SameSiteMode.Lax.
Nuovo comportamento
Tutte le API interessate usano per impostazione predefinita SameSiteMode.None.
Motivo della modifica
Il valore predefinito è stato modificato per rendere SameSite una funzionalità che prevede il consenso esplicito.
Azione consigliata
Ogni componente che genera cookie deve decidere se SameSite è appropriato per i propri scenari. Esaminare l'utilizzo delle API interessate e riconfigurare SameSite in base alle esigenze.
A partire da ASP.NET Core 3.0, le operazioni server sincrone sono disabilitate per impostazione predefinita.
Descrizione delle modifiche
AllowSynchronousIO è un'opzione presente in ogni server che abilita o disabilita le API di I/O sincrone come HttpRequest.Body.Read, HttpResponse.Body.Write e Stream.Flush. Queste API sono state a lungo la causa di blocchi delle app e mancanza di risorse dei thread. A partire da ASP.NET Core 3.0 Preview 3, queste operazioni sincrone sono disabilitate per impostazione predefinita.
Server interessati:
Kestrel
HttpSys
IIS in-process
TestServer
Si prevedono errori simili a:
Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.
Ogni server ha un'opzione AllowSynchronousIO che controlla questo comportamento e il valore predefiniti per tutti i server è ora false.
Come mitigazione temporanea, il comportamento può anche essere sottoposto a override in base a singole richieste. Ad esempio:
var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
syncIOFeature.AllowSynchronousIO = true;
}
Se si verificano problemi con un elemento TextWriter o un altro flusso che chiama un'API sincrona in Dispose, chiamare invece la nuova API DisposeAsync.
Le API HttpRequest.Body.Read, HttpResponse.Body.Write e Stream.Flush erano consentite per impostazione predefinita.
Nuovo comportamento
Queste API sincrone non sono consentite per impostazione predefinita:
Si prevedono errori simili a:
Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.
Motivo della modifica
Queste API sincrone sono state a lungo la causa di blocchi delle app e mancanza di risorse dei thread. A partire da ASP.NET Core 3.0 Preview 3, le operazioni sincrone sono disabilitate per impostazione predefinita.
Azione consigliata
Usare le versioni asincrone dei metodi. Come mitigazione temporanea, il comportamento può anche essere sottoposto a override in base a singole richieste.
var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
syncIOFeature.AllowSynchronousIO = true;
}
Identity: versione predefinita di Bootstrap dell'interfaccia utente modificata
A partire da ASP.NET Core 3.0, l'interfaccia utente di Identity usa per impostazione predefinita la versione 4 di Bootstrap.
Versione introdotta
3,0
Comportamento precedente
La chiamata al metodo services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(); equivaleva a services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap3);
Nuovo comportamento
La chiamata al metodo services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(); equivale a services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap4);
Motivo della modifica
Bootstrap 4 è stato rilasciato durante il periodo di ASP.NET Core 3.0.
Azione consigliata
Si è interessati da questa modifica se si usa l'interfaccia utente predefinita di Identity e la si è aggiunta in Startup.ConfigureServices, come illustrato nell'esempio seguente:
Identity: SignInAsync genera un'eccezione per l'identità non autenticata
Per impostazione predefinita, SignInAsync genera un'eccezione per le entità di sicurezza/identità in cui IsAuthenticated è false.
Versione introdotta
3,0
Comportamento precedente
SignInAsync accetta qualsiasi entità di sicurezza/identità, incluse le identità in cui IsAuthenticated è false.
Nuovo comportamento
Per impostazione predefinita, SignInAsync genera un'eccezione per le entità di sicurezza/identità in cui IsAuthenticated è false. È disponibile un nuovo flag per eliminare questo comportamento, ma il comportamento predefinito è cambiato.
Motivo della modifica
Il comportamento precedente causava problemi perché, per impostazione predefinita, queste entità erano rifiutate da [Authorize] / RequireAuthenticatedUser().
Azione consigliata
In ASP.NET Core 3.0 Preview 6 c'è un flag RequireAuthenticatedSignIn in AuthenticationOptions che per impostazione predefinita è true. Impostare questo flag su false per ripristinare il comportamento precedente.
Category
ASP.NET Core
API interessate
None
Identity: il costruttore SignInManager accetta un nuovo parametro
A partire da ASP.NET Core 3.0, al costruttore SignInManager è stato aggiunto un nuovo parametro IUserConfirmation<TUser>. Per altre informazioni, vedere dotnet/aspnetcore#8356.
Versione introdotta
3,0
Motivo della modifica
Il motivo della modifica è stato l'aggiunta del supporto per i nuovi flussi di posta elettronica/conferma in Identity.
Azione consigliata
Se si costruisce manualmente un elemento SignInManager, fornire un'implementazione di IUserConfirmation o recuperarne una da fornire dall'inserimento delle dipendenze.
Identity: l'interfaccia utente usa la funzionalità degli asset Web statici
In ASP.NET Core 3.0 è stata introdotta una funzionalità di asset Web statici e l'interfaccia utente di Identity l'ha adottata.
Descrizione delle modifiche
In seguito all'adozione della funzionalità degli asset Web statici nell'interfaccia utente di Identity:
La selezione del framework viene eseguita usando la proprietà IdentityUIFrameworkVersion nel file di progetto.
Bootstrap 4 è il framework di interfaccia utente predefinito per l'interfaccia utente di Identity. Bootstrap 3 ha raggiunto la fine del ciclo di vita ed è consigliabile eseguire la migrazione a una versione supportata.
Versione introdotta
3,0
Comportamento precedente
Il framework di interfaccia utente predefinito per l'interfaccia utente di Identity era Bootstrap 3. Si poteva configurare il framework di interfaccia utente usando un parametro per la chiamata al metodo AddDefaultUI in Startup.ConfigureServices.
Nuovo comportamento
Il framework di interfaccia utente predefinito per l'interfaccia utente di Identity è Bootstrap 4. Il framework di interfaccia utente deve essere configurato nel file di progetto anziché nella chiamata al metodo AddDefaultUI.
Motivo della modifica
L'adozione della funzionalità degli asset Web statici richiedeva che la configurazione del framework di interfaccia utente passasse a MSBuild. La decisione su quale framework incorporare è una decisione da prendere in fase di compilazione, non in fase di runtime.
Azione consigliata
Esaminare l'interfaccia utente del sito per assicurarsi che i nuovi componenti Bootstrap 4 siano compatibili. Se necessario, usare la proprietà IdentityUIFrameworkVersion di MSBuild per ripristinare Bootstrap 3. Aggiungere la proprietà a un elemento <PropertyGroup> nel file di progetto:
Nell'ambito della modifica delle API "pubternal" in public, il concetto di IConnectionAdapter è stato rimosso da Kestrel. Gli adapter di connessione sono stati sostituiti dal middleware di connessione (simile al middleware HTTP nella pipeline di ASP.NET Core, ma per le connessioni di livello inferiore). La registrazione delle connessioni e HTTPS sono stati spostati dagli adapter di connessione al middleware di connessione. Questi metodi di estensione dovrebbero continuare a funzionare senza problemi, ma i dettagli di implementazione sono cambiati.
In ASP.NET Core 2.1, il contenuto di Microsoft.AspNetCore.Server.Kestrel.Https è stato spostato in Microsoft.AspNetCore.Server.Kestrel.Core. Questa modifica è stata eseguita in una modalità che non causa interruzioni usando attributi [TypeForwardedTo].
Azione consigliata
Le librerie che fanno riferimento a Microsoft.AspNetCore.Server.Kestrel.Https 2.0 devono aggiornare tutte le dipendenze di ASP.NET Core alla versione 2.1 o successiva. In caso contrario, possono bloccarsi quando vengono caricate in un'app ASP.NET Core 3.0.
Le app e le librerie destinate ad ASP.NET Core 2.1 e versioni successive devono rimuovere qualunque riferimento diretto al pacchetto NuGet Microsoft.AspNetCore.Server.Kestrel.Https.
Category
ASP.NET Core
API interessate
None
Kestrel: intestazioni Trailer della richiesta spostate in una nuova raccolta
Nelle versioni precedenti, Kestrel aggiungeva intestazioni Trailer in blocchi HTTP/1.1 nella raccolta delle intestazioni delle richieste quando il corpo della richiesta veniva letto in corrispondenza della fine. Questo comportamento causava preoccupazioni sull'ambiguità tra intestazioni e trailer. È stata presa la decisione di spostare i trailer in una nuova raccolta.
I trailer delle richieste HTTP/2 non erano disponibili in ASP.NET Core 2.2, ma ora sono disponibili in questa nuova raccolta in ASP.NET Core 3.0.
Sono stati aggiunti nuovi metodi di estensione della richiesta per accedere a questi trailer.
I trailer HTTP/1.1 sono disponibili dopo la lettura dell'intero corpo della richiesta.
I trailer HTTP/2 sono disponibili una volta ricevuti dal client. Il client non invierà i trailer finché l'intero corpo della richiesta non è stato almeno memorizzato nel buffer dal server. Può essere necessario leggere il corpo della richiesta per liberare spazio di buffer. I trailer sono sempre disponibili se si legge il corpo della richiesta nella parte finale. I trailer contrassegnano la fine del corpo.
Versione introdotta
3,0
Comportamento precedente
Le intestazioni Trailer della richiesta venivano aggiunte alla raccolta HttpRequest.Headers.
Nuovo comportamento
Le intestazioni Trailer della richiesta non sono presenti nella raccolta HttpRequest.Headers. Usare i metodi di estensione seguenti in HttpRequest per accedervi:
GetDeclaredTrailers() - Ottiene l'intestazione "Trailer" della richiesta che elenca i trailer previsti dopo il corpo.
SupportsTrailers() - Indica se la richiesta supporta la ricezione di intestazioni Trailer.
CheckTrailersAvailable() - Determina se la richiesta supporta i trailer e se sono disponibili per la lettura.
GetTrailer(string trailerName) - Ottiene l'intestazione Trailer richiesta dalla risposta.
Motivo della modifica
I trailer sono una funzionalità chiave in scenari come gRPC. L'unione dei trailer alle intestazioni delle richieste causava confusione negli utenti.
Azione consigliata
Usare i metodi di estensione correlati ai trailer in HttpRequest per accedere ai trailer.
Kestrel: astrazioni di trasporto rimosse e rese pubbliche
Nel quadro dell'abbandono delle API "pubternal", le API del livello di trasporto di Kestrel vengono esposte come interfaccia pubblica nella libreria Microsoft.AspNetCore.Connections.Abstractions.
Versione introdotta
3,0
Comportamento precedente
Le astrazioni correlate al trasporto erano disponibili nella libreria Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.
Era disponibile la proprietà ListenOptions.NoDelay.
Nuovo comportamento
L'interfaccia IConnectionListener è stata introdotta nella libreria Microsoft.AspNetCore.Connections.Abstractions per esporre le funzionalità più usate dalla libreria ...Transport.Abstractions.
Ora nelle opzioni di trasporto è disponibile NoDelay (LibuvTransportOptions e SocketTransportOptions).
SchedulingMode non è più disponibile.
Motivo della modifica
ASP.NET Core 3.0 ha abbandonato l'uso delle API "pubternal".
Azione consigliata
Category
ASP.NET Core
API interessate
None
Localizzazione: ResourceManagerWithCultureStringLocalizer e WithCulture contrassegnati come obsoleti
La classe ResourceManagerWithCultureStringLocalizer e il membro dell'interfaccia WithCulture sono spesso fonte di confusione per gli utenti della localizzazione, in particolare quando creano la propria implementazione di IStringLocalizer. Questi elementi danno all'utente l'impressione che un'istanza di IStringLocalizer sia per lingua e per risorsa. In realtà, le istanze devono essere solo per risorsa. Il linguaggio cercato è determinato dall'elemento CultureInfo.CurrentUICulture in fase di esecuzione. Per eliminare la fonte della confusione, le API sono state contrassegnate come obsolete in ASP.NET Core 3.0. Le API verranno rimosse in una versione futura.
I metodi non sono stati contrassegnati come Obsolete.
Nuovo comportamento
I metodi sono contrassegnati come Obsolete.
Motivo della modifica
Le API rappresentavano un caso d'uso non consigliato. C'era confusione sulla progettazione della localizzazione.
Azione consigliata
È consigliabile usare ResourceManagerStringLocalizer. Lasciare che le impostazioni cultura siano impostate da CurrentCulture. Se non è possibile, creare e usare una copia di ResourceManagerWithCultureStringLocalizer.
Prima di ASP.NET Core 3.0, il modificatore di accesso di DebugLogger era public. In ASP.NET Core 3.0 il modificatore di accesso è diventato internal.
Versione introdotta
3,0
Motivo della modifica
La modifica è stata apportata per:
Garantire la coerenza con altre implementazioni del logger, ad esempio ConsoleLogger.
Ridurre la superficie dell'API.
Azione consigliata
Usare il metodo di estensione AddDebugILoggingBuilder per abilitare la registrazione di debug. DebugLoggerProvider è ancora public, nel caso in cui il servizio debba essere registrato manualmente.
Category
ASP.NET Core
API interessate
Microsoft.Extensions.Logging.Debug.DebugLogger
MVC: suffisso Async rimosso dai nomi delle azioni del controller
Come parte della soluzione del problema dotnet/aspnetcore#4849, ASP.NET Core MVC elimina il suffisso Async dai nomi delle azioni per impostazione predefinita. A partire da ASP.NET Core 3.0, questa modifica influisce sia sul routing che sulla generazione di collegamenti.
Versione introdotta
3,0
Comportamento precedente
Considerare il controller ASP.NET Core MVC seguente:
public class ProductController : Controller
{
public async IActionResult ListAsync()
{
var model = await DbContext.Products.ToListAsync();
return View(model);
}
}
L'azione è instradabile tramite Product/ListAsync. Per la generazione di collegamenti occorre specificare il suffisso Async. Ad esempio:
In ASP.NET Core 3.0 l'azione può essere instradata tramite Product/List. Il codice di generazione del collegamento deve omettere il suffisso Async. Ad esempio:
Questa modifica non influisce sui nomi specificati usando l'attributo [ActionName]. È possibile disabilitare il nuovo comportamento impostando MvcOptions.SuppressAsyncSuffixInActionNames su false in Startup.ConfigureServices:
Per convenzione, i metodi .NET asincroni hanno il suffisso Async. Tuttavia, quando un metodo definisce un'azione MVC, non è consigliabile usare il suffisso Async.
Azione consigliata
Se per l'app è necessario che le azioni MVC conservino il suffisso Async del nome, scegliere una delle mitigazioni seguenti:
Usare l'attributo [ActionName] per mantenere il nome originale.
Disabilitare completamente la ridenominazione impostando MvcOptions.SuppressAsyncSuffixInActionNames su false in Startup.ConfigureServices:
MVC: JsonResult spostato in Microsoft.AspNetCore.Mvc.Core
JsonResult è stato spostato nell'assembly Microsoft.AspNetCore.Mvc.Core. Questo tipo era definito in Microsoft.AspNetCore.Mvc.Formatters.Json. Per risolvere questo problema per la maggior parte degli utenti, in Microsoft.AspNetCore.Mvc.Formatters.Json è stato aggiunto un attributo [TypeForwardedTo] a livello di assembly. Le app che usano librerie di terze parti possono riscontrare problemi.
Versione introdotta
3.0 Preview 6
Comportamento precedente
Un'app che usa una libreria basata su 2.2 viene compilata correttamente.
Nuovo comportamento
La compilazione di un'app che usa una libreria basata su 2.2 non riesce. Viene visualizzato un errore contenente un errore simile al seguente:
The type 'JsonResult' exists in both 'Microsoft.AspNetCore.Mvc.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' and 'Microsoft.AspNetCore.Mvc.Formatters.Json, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
Modifiche a livello di piattaforma alla composizione di ASP.NET Core, come descritto in aspnet/Announcements#325.
Azione consigliata
Potrebbe essere necessario ricompilare le librerie compilate per la versione 2.2 di Microsoft.AspNetCore.Mvc.Formatters.Json per risolvere il problema per tutti i consumer. Se si è interessati dal problema, rivolgersi all'autore della libreria. Chiedere la ricompilazione della libreria per la destinazione ASP.NET Core 3.0.
In ASP.NET Core 1.1 è stato introdotto il pacchetto Microsoft.AspNetCore.Mvc.Razor.ViewCompilation (strumento di precompilazione MVC) per aggiungere il supporto per la compilazione in fase di pubblicazione dei file Razor (.cshtml). In ASP.NET Core 2.1 è stato introdotto Razor SDK, per ampliare le funzionalità dello strumento di precompilazione. Razor SDK ha aggiunto il supporto per la compilazione di file Razor in fase di compilazione e pubblicazione. L'SDK verifica la correttezza dei file.cshtml in fase di compilazione, migliorando inoltre il tempo di avvio dell'app. Razor SDK è attivato per impostazione predefinita e non è necessario alcun intervento per iniziare a usarlo.
In ASP.NET Core 3.0, lo strumento di precompilazione MVC di ASP.NET Core 1.1 è stato rimosso. Le versioni precedenti del pacchetto continueranno a ricevere importanti correzioni di bug e per sicurezza nelle versioni patch.
Versione introdotta
3,0
Comportamento precedente
Il pacchetto Microsoft.AspNetCore.Mvc.Razor.ViewCompilation era usato per precompilare le visualizzazioni Razor di MVC.
Nuovo comportamento
Razor SDK supporta questa funzionalità in modo nativo. Il pacchetto Microsoft.AspNetCore.Mvc.Razor.ViewCompilation non viene più aggiornato.
Motivo della modifica
Razor SDK offre più funzionalità e verifica la correttezza dei file .cshtml in fase di compilazione. L'SDK migliora anche il tempo di avvio dell'app.
Azione consigliata
Per gli utenti di ASP.NET Core 2.1 o versione successiva, eseguire l'aggiornamento in modo da usare il supporto nativo per la precompilazione in Razor SDK. Se la presenza di bug o la mancanza di funzionalità impediscono la migrazione a Razor SDK, aprire un problema in dotnet/aspnetcore.
Category
ASP.NET Core
API interessate
None
MVC: tipi "pubternal" modificati in interni
In ASP.NET Core 3.0 tutti i tipi "pubternal" di MVC sono stati aggiornati per essere public in uno spazio dei nomi supportato oppure internal in base alle esigenze.
Descrizione delle modifiche
In ASP.NET Core i tipi "pubternal" vengono dichiarati come public, ma risiedono in uno spazio dei nomi con suffisso .Internal. Sebbene questi tipi siano public, non hanno criteri di supporto e sono soggetti a modifiche che causano un'interruzione. Sfortunatamente, l'uso accidentale di questi tipi è stato frequente, dando luogo a modifiche che causano interruzioni in questi progetti e limitando la capacità di gestire il framework.
Versione introdotta
3,0
Comportamento precedente
Alcuni tipi in MVC erano public, ma in uno spazio dei nomi .Internal. Questi tipi non avevano criteri di supporto ed erano soggetti a modifiche causano un'interruzione.
Nuovo comportamento
Tutti questi tipi vengono aggiornati in modo che siano public in uno spazio dei nomi supportato oppure contrassegnati come internal.
Motivo della modifica
L'uso accidentale dei tipi "pubternal" è stato frequente, dando luogo a modifiche che causano un'interruzione in questi progetti e limitando la capacità di gestire il framework.
Azione consigliata
Se si usano tipi che sono diventati realmente public e sono stati spostati in un nuovo spazio dei nomi supportato, aggiornare i riferimenti in modo che corrispondano ai nuovi spazi dei nomi.
Se si usano tipi che sono stati contrassegnati come internal, sarà necessario trovare un'alternativa. I tipi precedentemente "pubternal" non sono mai stati supportati per l'utilizzo pubblico. Se in questi spazi dei nomi sono presenti tipi specifici di importanza critica per le app, segnalare il problema alla pagina dotnet/aspnetcore. Si potrebbe valutare di rendere public i tipi richiesti.
Category
ASP.NET Core
API interessate
Questa modifica include i tipi negli spazi dei nomi seguenti:
Microsoft.AspNetCore.Mvc.Cors.Internal
Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
Microsoft.AspNetCore.Mvc.Formatters.Internal
Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
Microsoft.AspNetCore.Mvc.Formatters.Xml.Internal
Microsoft.AspNetCore.Mvc.Internal
Microsoft.AspNetCore.Mvc.ModelBinding.Internal
Microsoft.AspNetCore.Mvc.Razor.Internal
Microsoft.AspNetCore.Mvc.RazorPages.Internal
Microsoft.AspNetCore.Mvc.TagHelpers.Internal
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
MVC: shim di compatibilità API Web rimosso
A partire da ASP.NET Core 3.0, il pacchetto Microsoft.AspNetCore.Mvc.WebApiCompatShim non è più disponibile.
Descrizione delle modifiche
Il pacchetto Microsoft.AspNetCore.Mvc.WebApiCompatShim (WebApiCompatShim) offre compatibilità parziale in ASP.NET Core con l'API Web 2 di ASP.NET 4.x per semplificare la migrazione delle implementazioni di API Web esistenti ad ASP.NET Core. Tuttavia, le app che usano WebApiCompatShim non traggono vantaggio dalle funzionalità correlate alle API disponibili nelle versioni recenti di ASP.NET Core. Tali funzionalità includono il miglioramento della generazione della specifica OpenAPI, la gestione degli errori standardizzata e la generazione di codice client. Per focalizzare meglio le iniziative rivolte alle API nella versione 3.0, WebApiCompatShim è stato rimosso. Le app esistenti che usano WebApiCompatShim devono eseguire la migrazione al modello più recente di [ApiController].
Versione introdotta
3,0
Motivo della modifica
Lo shim di compatibilità dell'API Web era uno strumento di migrazione. Limita l'accesso degli utenti alle nuove funzionalità aggiunte in ASP.NET Core.
Azione consigliata
Rimuovere l'utilizzo di questo shim ed eseguire direttamente la migrazione alla funzionalità analoga in ASP.NET Core stesso.
È possibile creare un motore di modelli e usarlo per analizzare e generare codice per i file Razor.
Nuovo comportamento
È possibile creare un'API RazorProjectEngine a cui fornire lo stesso tipo di informazioni di RazorTemplateEngine per analizzare e generare codice per i file Razor. RazorProjectEngine fornisce anche livelli di configurazione aggiuntivi.
Motivo della modifica
L'API RazorTemplateEngine era accoppiata troppo strettamente alle implementazioni esistenti. Questo accoppiamento stretto generava ulteriori problemi nel tentativo di configurare correttamente una pipeline di analisi/generazione Razor.
Azione consigliata
Usare RazorProjectEngine invece di RazorTemplateEngine. Si considerino gli esempi seguenti.
Creare e configurare RazorProjectEngine
RazorProjectEngine projectEngine =
RazorProjectEngine.Create(RazorConfiguration.Default,
RazorProjectFileSystem.Create(@"C:\source\repos\ConsoleApp4\ConsoleApp4"),
builder =>
{
builder.ConfigureClass((document, classNode) =>
{
classNode.ClassName = "MyClassName";
// Can also configure other aspects of the class here.
});
// More configuration can go here
});
In precedenza erano disponibili le API seguenti in Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions per supportare la compilazione in fase di esecuzione. Ora le API sono disponibili tramite Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.MvcRazorRuntimeCompilationOptions.
RazorViewEngineOptions.FileProviders è ora MvcRazorRuntimeCompilationOptions.FileProviders
RazorViewEngineOptions.AdditionalCompilationReferences è ora MvcRazorRuntimeCompilationOptions.AdditionalReferencePaths
Inoltre, Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions.AllowRecompilingViewsOnFileChange è stato rimosso. La ricompilazione alla modifica dei file è abilitata per impostazione predefinita facendo riferimento al pacchetto Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.
Motivo della modifica
Questa modifica è stata necessaria per rimuovere la dipendenza del framework condiviso di ASP.NET Core da Roslyn.
Azione consigliata
Per le app che richiedono la compilazione in fase di esecuzione o la ricompilazione dei file Razor occorre seguire questa procedura:
Aggiungere un riferimento al pacchetto Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.
Aggiornare il metodo Startup.ConfigureServices del progetto per includere una chiamata a AddRazorRuntimeCompilation. Ad esempio:
Le API obsolete per la configurazione dei cookie di sessione sono state rimosse. Per altre informazioni, vedere aspnet/Announcements#257.
Versione introdotta
3,0
Motivo della modifica
Questa modifica assicura la coerenza tra le API per la configurazione delle funzionalità che usano i cookie.
Azione consigliata
Eseguire la migrazione delle app all'utilizzo delle nuove API al posto di quelle rimosse. Si consideri l'esempio seguente in Startup.ConfigureServices:
Framework condiviso: assembly rimossi da Microsoft.AspNetCore.App
A partire da ASP.NET Core 3.0, il framework condiviso ASP.NET Core (Microsoft.AspNetCore.App) contiene solo assembly proprietari completamente sviluppati, supportati e mantenuti da Microsoft.
Descrizione delle modifiche
Si può considerare la modifica una ridefinizione dei limiti per la "piattaforma" ASP.NET Core. Tramite GitHub, chiunque potrà compilare il codice sorgente del framework condiviso, che continuerà a offrire gli attuali vantaggi dei framework condivisi di .NET Core alle app. Alcuni di questi vantaggi includono dimensioni di distribuzione minori, applicazione centralizzata delle patch e tempi di avvio più rapidi.
Come parte della modifica, in Microsoft.AspNetCore.App sono state introdotte alcune modifiche di rilievo che causano un'interruzione.
Versione introdotta
3,0
Comportamento precedente
I progetti facevano riferimento a Microsoft.AspNetCore.App tramite un elemento <PackageReference> nel file di progetto.
Inoltre, Microsoft.AspNetCore.App conteneva i sottocomponenti seguenti:
Json.NET (Newtonsoft.Json)
Entity Framework Core (assembly con prefisso Microsoft.EntityFrameworkCore.)
Roslyn (Microsoft.CodeAnalysis)
Nuovo comportamento
Un riferimento a Microsoft.AspNetCore.App non richiede più un elemento <PackageReference> nel file di progetto. .NET Core SDK supporta un nuovo elemento denominato <FrameworkReference>, che sostituisce l'uso di <PackageReference>.
Entity Framework Core viene distribuito sotto forma di pacchetti NuGet. Questa modifica allinea il modello di distribuzione a quello di tutte le altre librerie di accesso ai dati in .NET. Fornisce a Entity Framework Core il percorso più semplice per continuare a innovare supportando le varie piattaforme .NET. Lo spostamento di Entity Framework Core all'esterno del framework condiviso non ha alcun impatto sul suo stato di libreria sviluppata, supportata e mantenuta da Microsoft. I criteri di supporto di .NET Core continuano a coprirla.
Json.NET ed Entity Framework Core continuano a funzionare con ASP.NET Core. Non saranno tuttavia inclusi nel framework condiviso.
Questa modifica semplifica l'utilizzo di Microsoft.AspNetCore.App e riduce la duplicazione tra pacchetti NuGet e framework condivisi.
Per altre informazioni sul motivo di questa modifica, vedere questo post di blog.
Azione consigliata
A partire da ASP.NET Core 3.0, non è più necessario per i progetti utilizzare gli assembly in Microsoft.AspNetCore.App come pacchetti NuGet. Per semplificare la scelta della destinazione e l'utilizzo del framework condiviso di ASP.NET Core, molti pacchetti NuGet forniti a partire da ASP.NET Core 1.0 non vengono più prodotti. Le API fornite da tali pacchetti sono ancora disponibili per le app usando un elemento <FrameworkReference> per fare riferimento a Microsoft.AspNetCore.App. Alcuni esempi di API comuni includono Kestrel, MVC e Razor.
Questa modifica non si applica a tutti i file binari a cui viene fatto riferimento tramite Microsoft.AspNetCore.App in ASP.NET Core 2.x. Le eccezioni rilevanti includono:
Le librerie Microsoft.Extensions che continuano a essere destinate a .NET Standard e che sono disponibili come pacchetti NuGet (vedere https://github.com/dotnet/extensions).
Le API prodotte dal team ASP.NET Core che non fanno parte di Microsoft.AspNetCore.App. Ad esempio, i componenti seguenti sono disponibili come pacchetti NuGet:
Entity Framework Core
Le API che forniscono l'integrazione di terze parti
Le estensioni a MVC che mantengono il supporto per Json.NET. Per supportare l'uso di Json.NET e MVC è disponibile un'API fornita come pacchetto NuGet. Per altri dettagli, vedere la guida alla migrazione di ASP.NET Core.
Il client .NET di SignalR continua a supportare .NET Standard e viene fornito come pacchetto NuGet. È progettato per l'utilizzo in molti runtime .NET, ad esempio Xamarin e UWP.
A partire da ASP.NET Core 3.0, il metapacchetto Microsoft.AspNetCore.All e il framework condiviso corrispondente Microsoft.AspNetCore.All non vengono più prodotti. Questo pacchetto è disponibile in ASP.NET Core 2.2 e continuerà a ricevere aggiornamenti di manutenzione in ASP.NET Core 2.1.
Versione introdotta
3,0
Comportamento precedente
Le app possono usare il metapacchetto Microsoft.AspNetCore.All per specificare come destinazione il framework condiviso Microsoft.AspNetCore.All in .NET Core.
Nuovo comportamento
.NET Core 3.0 non include un framework condiviso Microsoft.AspNetCore.All.
Motivo della modifica
Il metapacchetto Microsoft.AspNetCore.All includeva un numero elevato di dipendenze esterne.
Azione consigliata
Eseguire la migrazione del progetto per usare il framework Microsoft.AspNetCore.App. I componenti precedentemente disponibili in Microsoft.AspNetCore.All sono ancora disponibili in NuGet. Ora questi componenti vengono distribuiti con l'app anziché essere inclusi nel framework condiviso.
Il campo HandshakeProtocol.SuccessHandshakeData è stato rimosso e sostituito con un metodo helper che genera una risposta handshake riuscito in funzione di uno specifico IHubProtocol.
Versione introdotta
3,0
Comportamento precedente
HandshakeProtocol.SuccessHandshakeData era un campo public static ReadOnlyMemory<byte>.
Nuovo comportamento
HandshakeProtocol.SuccessHandshakeData è stato sostituito da un metodo staticGetSuccessfulHandshake(IHubProtocol protocol) che restituisce un elemento ReadOnlyMemory<byte> in base al protocollo specificato.
Motivo della modifica
Alla risposta handshake sono stati aggiunti campi non costanti, che cambiano a seconda del protocollo selezionato.
Azione consigliata
Nessuno. Questo tipo non è progettato per l'uso a partire dal codice utente. È public, quindi può essere condiviso tra il server SignalR e il client. Può essere usato anche dai client SignalR dei clienti scritti in .NET. Gli utenti di SignalR non dovrebbero essere interessati da questa modifica.
SignalR: metodi ResetSendPing e ResetTimeout di HubConnection rimossi
I metodi ResetSendPing e ResetTimeout sono stati rimossi dall'API HubConnection di SignalR. Questi metodi erano originariamente progettati solo per l'uso interno, ma sono stati resi pubblici in ASP.NET Core 2.2. A partire dalla versione ASP.NET Core 3.0 Preview 4, non saranno più disponibili. Per informazioni, vedere dotnet/aspnetcore#8543.
Versione introdotta
3,0
Comportamento precedente
Le API erano disponibili.
Nuovo comportamento
Le API sono state rimosse.
Motivo della modifica
Questi metodi in origine erano progettati solo per l'uso interno, ma sono stati resi pubblici in ASP.NET Core 2.2.
I costruttori HubConnectionContext di SignalR sono stati modificati in modo da accettare un tipo options anziché più parametri, per garantire la possibilità di aggiungere opzioni in futuro. Questa modifica sostituisce due costruttori con un singolo costruttore che accetta un tipo Options.
Versione introdotta
3,0
Comportamento precedente
HubConnectionContext ha due costruttori:
public HubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory);
public HubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory, TimeSpan clientTimeoutInterval);
Nuovo comportamento
I due costruttori sono stati rimossi e sostituiti con un costruttore:
public HubConnectionContext(ConnectionContext connectionContext, HubConnectionContextOptions contextOptions, ILoggerFactory loggerFactory)
Motivo della modifica
Il nuovo costruttore usa un nuovo oggetto Options. Di conseguenza, in futuro sarà possibile espandere le funzionalità di HubConnectionContext senza creare altri costruttori e apportare modifiche che causano un'interruzione.
SignalR: modifica del nome del pacchetto client JavaScript
In ASP.NET Core 3.0 Preview 7 il nome del pacchetto client JavaScript di SignalR è cambiato da @aspnet/signalr a @microsoft/signalr. La modifica del nome riflette il fatto che SignalR non è utile soltanto per le app ASP.NET Core, grazie al Servizio Azure SignalR.
Per reagire a questa modifica, modificare i riferimenti nei file package.json, nelle istruzioni require e nelle istruzioni import ECMAScript. Nessuna API verrà modificata come parte di questa ridenominazione.
Applicazioni a pagina singola: SpaServices e NodeServices contrassegnati come obsoleti
Il contenuto dei pacchetti NuGet seguenti non è più necessario a partire da ASP.NET Core 2.1. Di conseguenza, i pacchetti seguenti sono contrassegnati come obsoleti:
I pacchetti e i moduli npm precedenti verranno successivamente rimossi in .NET 5.
Versione introdotta
3,0
Comportamento precedente
I pacchetti e i moduli npm deprecati erano progettati per integrare ASP.NET Core con vari framework per app a pagina singola. Tali framework includono Angular, React e React con Redux.
Nuovo comportamento
È disponibile un nuovo meccanismo di integrazione nel pacchetto NuGet Microsoft.AspNetCore.SpaServices.Extensions. Il pacchetto resta la base dei modelli di progetto Angular e React a partire da ASP.NET Core 2.1.
Motivo della modifica
ASP.NET Core supporta l'integrazione con vari framework per app a pagina singola, tra cui Angular, React e React con Redux. Inizialmente, l'integrazione con questi framework veniva eseguita con componenti specifici di ASP.NET Core che gestivano scenari come il rendering preliminare lato server e l'integrazione con Webpack. Col passare del tempo, gli standard del settore sono cambiati. Tutti i framework per app a pagina singola hanno rilasciato le proprie interfacce della riga di comando standard, ad esempio, Angular CLI e create-react-app.
Quando è stato rilasciato ASP.NET Core 2.1, nel maggio 2018, il team ha risposto alla modifica degli standard. È stato fornito un modo più semplice e nuovo per l'integrazione con le toolchain proprietarie dei framework per app a pagina singola. Il nuovo meccanismo di integrazione si trova nel pacchetto Microsoft.AspNetCore.SpaServices.Extensions e rimane la base dei modelli di progetto Angular e React a partire da ASP.NET Core 2.1.
Per chiarire che i componenti specifici di ASP.NET Core precedenti sono irrilevanti e non sono consigliati:
Il meccanismo di integrazione precedente alla versione 2.1 è contrassegnato come obsoleto.
I pacchetti npm di supporto sono contrassegnati come deprecati.
Azione consigliata
Se si usano questi pacchetti, aggiornare le app in modo da usare la funzionalità:
Nel pacchetto Microsoft.AspNetCore.SpaServices.Extensions.
Fornita dai framework per app a pagina singola in uso
Per abilitare funzionalità come il rendering preliminare lato server e il ricaricamento rapido dei moduli, vedere la documentazione del framework per app a pagina singola corrispondente. La funzionalità in Microsoft.AspNetCore.SpaServices.Extensionsnon è obsoleta e continuerà a essere supportata.
Microsoft.AspNetCore.SpaServices e Microsoft.AspNetCore.NodeServices creavano automaticamente un logger della console quando la registrazione non è configurata.
Nuovo comportamento
Microsoft.AspNetCore.SpaServices e Microsoft.AspNetCore.NodeServices non visualizzeranno i log della console a meno che non sia configurata la registrazione.
Motivo della modifica
È necessario allineare il modo in cui gli altri pacchetti ASP.NET Core implementano la registrazione.
Azione consigliata
Se è necessario il comportamento precedente, per configurare la registrazione della console aggiungere services.AddLogging(builder => builder.AddConsole()) al metodoSetup.ConfigureServices.
Category
ASP.NET Core
API interessate
None
Framework di destinazione: supporto di .NET Framework rimosso
A partire da ASP.NET Core 3.0, .NET Framework è un framework di destinazione non supportato.
Descrizione delle modifiche
.NET Framework 4.8 è l'ultima versione principale di .NET Framework. Le nuove app ASP.NET Core devono essere basate su .NET Core. A partire dalla versione .NET Core 3.0, si può considerare ASP.NET Core 3.0 come parte di .NET Core.
I clienti che usano ASP.NET Core con .NET Framework possono continuare in una modalità completamente supportata usando la versione 2.1 LTS. Il supporto e la manutenzione per la versione 2.1 proseguiranno fino al 21 agosto 2021. Questa data è di tre anni successiva alla dichiarazione della versione LTS in base ai criteri di supporto di .NET. Il supporto per i pacchetti ASP.NET Core 2.1 in .NET Framework continuerà a tempo indeterminato, in modo analogo ai criteri di manutenzione di altri framework ASP.NET basati su pacchetti.
Per altre informazioni sulla conversione da .NET Framework a .NET Core, vedere Conversione a .NET Core.
I Microsoft.Extensions pacchetti, ad esempio per la registrazione, l'inserimento delle dipendenze e la configurazione, ed Entity Framework Core non sono interessati. Continueranno a supportare .NET Standard.
Le API che segnalano la versione ora segnalano la versione del prodotto e non quella del file
Molte API che restituiscono le versioni in .NET Core restituiscono ora la versione del prodotto anziché la versione del file.
Descrizione delle modifiche
In .NET Core 2.2 e versioni precedenti, i metodi come Environment.Version, RuntimeInformation.FrameworkDescription e la finestra di dialogo delle proprietà del file per gli assembly .NET Core riflettono la versione del file. A partire da .NET Core 3.0, riflettono la versione del prodotto.
La figura seguente illustra la differenza nelle informazioni sulla versione dell'assembly System.Runtime.dll per .NET Core 2.2 (a sinistra) e .NET Core 3.0 (a destra) così come visualizzate nella finestra di dialogo delle proprietà del file di Esplora risorse.
Versione introdotta
3,0
Azione consigliata
Nessuno. Questa modifica dovrebbe rendere più intuitivo il rilevamento della versione.
Le istanze personalizzate di EncoderFallbackBuffer non possono eseguire il fallback in modo ricorsivo
Le istanze personalizzate di EncoderFallbackBuffer non possono eseguire il fallback in modo ricorsivo. L'implementazione di EncoderFallbackBuffer.GetNextChar() deve produrre una sequenza di caratteri convertibile nella codifica di destinazione. In caso contrario, viene generata un'eccezione.
Descrizione delle modifiche
Durante un'operazione di transcodifica da carattere a byte, il runtime rileva le sequenze UTF-16 in formato non corretto o non convertibili e fornisce tali caratteri al metodo EncoderFallbackBuffer.Fallback. Il metodo Fallback determina quali caratteri vanno sostituiti per i dati originali non convertibili e questi caratteri vengono eliminati chiamando EncoderFallbackBuffer.GetNextChar in un ciclo.
Il runtime tenta quindi di transcodificare questi caratteri sostitutivi nella codifica di destinazione. Se l'operazione ha esito positivo, il runtime continua la transcodifica dal punto in cui è stata interrotta nella stringa di input originale.
Nelle versioni precedenti, le implementazioni personalizzate di EncoderFallbackBuffer.GetNextChar() possono restituire sequenze di caratteri non convertibili nella codifica di destinazione. Se non è possibile transcodificare i caratteri sostituiti nella codifica di destinazione, il runtime richiama nuovamente il metodo EncoderFallbackBuffer.Fallback con i caratteri di sostituzione, aspettandosi che il metodo EncoderFallbackBuffer.GetNextChar() restituisca una nuova sequenza di sostituzione. Questo processo continua fino a quando il runtime non ottiene una sostituzione in formato corretto e convertibile o finché non viene raggiunto il numero massimo di ricorsioni.
A partire da .NET Core 3.0, le implementazioni personalizzate di EncoderFallbackBuffer.GetNextChar() devono restituire sequenze di caratteri convertibili nella codifica di destinazione. Se i caratteri sostituiti non possono essere transcodificati nella codifica di destinazione, viene generata un'eccezione ArgumentException. Il runtime non effettuerà più chiamate ricorsive all'istanza di EncoderFallbackBuffer.
Questo comportamento si applica solo quando vengono soddisfatte tutte e tre le condizioni seguenti:
Il runtime rileva una sequenza UTF-16 in formato non corretto o che non può essere convertita nella codifica di destinazione.
È stato specificato un elemento EncoderFallback personalizzato.
L'istanza personalizzata di EncoderFallback prova a sostituire una nuova sequenza UTF-16 in formato non corretto o non convertibile.
Versione introdotta
3,0
Azione consigliata
La maggior parte degli sviluppatori non deve fare nulla.
Se un'applicazione usa un elemento EncoderFallback e una classe EncoderFallbackBuffer personalizzati, assicurati che l'implementazione di EncoderFallbackBuffer.Fallback popoli il buffer di fallback con dati UTF-16 in formato corretto e direttamente convertibili nella codifica di destinazione la prima volta che il runtime richiama il metodo Fallback.
Comportamento di formattazione e analisi a virgola mobile modificato
Il comportamento di analisi e formattazione a virgola mobile (in base ai tipi Double e Single) è ora conforme allo standard IEEE. Questo assicura che il comportamento dei tipi a virgola mobile in .NET corrisponda a quello di altri linguaggi conformi allo standard IEEE. Ad esempio, double.Parse("SomeLiteral") deve corrispondere sempre a quello che C# produce per double x = SomeLiteral.
Descrizione delle modifiche
In .NET Core 2.2 e versioni precedenti, la formattazione con Double.ToString e Single.ToString e l'analisi con Double.Parse, Double.TryParse, Single.Parse e Single.TryParse non sono conformi allo standard IEEE. Di conseguenza, è impossibile garantire che un valore esegua il round trip con qualunque stringa di formato standard o personalizzato compatibile. Per alcuni input il tentativo di analizzare un valore formattato può avere esito negativo, mentre per altri il valore analizzato non equivale al valore originale.
A partire da .NET Core 3.0, le operazioni di analisi e formattazione a virgola mobile sono compatibili con lo standard IEEE 754.
La tabella seguente mostra due frammenti di codice e il modo in cui l'output cambia tra .NET Core 2.2 e .NET Core 3.1.
Frammento di codice
Output in .NET Core 2.2
Output in .NET Core 3.1
Console.WriteLine((-0.0).ToString());
0
0-
var value = -3.123456789123456789; Console.WriteLine(value == double.Parse(value.ToString()));
Per alcune differenze nella formattazione, è possibile ottenere un comportamento equivalente al precedente specificando una stringa di formato diversa.
Per le differenze nell'analisi, non esiste alcun meccanismo per eseguire il fallback al comportamento precedente.
Le operazioni di analisi a virgola mobile non hanno più esito negativo né generano un'eccezione OverflowException
I metodi di analisi a virgola mobile non generano più un'eccezione OverflowException o restituiscono false quando analizzano una stringa il cui valore numerico non è compreso nell'intervallo del tipo a virgola mobile Single o Double.
Descrizione delle modifiche
In .NET Core 2.2 e versioni precedenti, i metodi Double.Parse e Single.Parse generano un'eccezione OverflowException per i valori che non rientrano nell'intervallo del rispettivo tipo. I metodi Double.TryParse e Single.TryParse restituiscono false per le rappresentazioni in forma di stringa di valori numerici non compresi nell'intervallo consentito.
Questa modifica è stata apportata per migliorare la conformità con lo standard IEEE 754-2008.
Versione introdotta
3,0
Azione consigliata
Questa modifica può influire sul codice in uno dei due modi seguenti:
Il codice dipende dal gestore per l'esecuzione di OverflowException quando si verifica un overflow. In questo caso, è necessario rimuovere l'istruzione catch e inserire qualsiasi codice necessario in un'istruzione If che verifica se Double.IsInfinity o Single.IsInfinity è true.
Il codice presuppone che i valori a virgola mobile non siano Infinity. In questo caso, è necessario aggiungere il codice necessario per verificare la presenza di valori a virgola mobile PositiveInfinity e NegativeInfinity.
In .NET Core 2.2 e versioni precedenti, la classe InvalidAsynchronousStateException si trova nell'assembly System.ComponentModel.TypeConverter.
A partire da .NET Core 3.0, si trova nell'assembly System.ComponentModel.Primitives.
Versione introdotta
3,0
Azione consigliata
Questa modifica influisce solo sulle applicazioni che usano la reflection per caricare InvalidAsynchronousStateException chiamando un metodo come Assembly.GetType o un overload di Activator.CreateInstance che presuppone che il tipo si trovi in un assembly specifico. In tal caso, aggiorna l'assembly a cui viene fatto riferimento nella chiamata al metodo per riflettere il nuovo percorso dell'assembly del tipo.
Category
Principali librerie .NET
API interessate
Nessuno.
La sostituzione delle sequenze di byte UTF-8 in formato non corretto segue le linee guida Unicode
Quando la classe UTF8Encoding rileva una sequenza di byte UTF-8 in formato non corretto durante un'operazione di transcodifica da byte a carattere, sostituisce tale sequenza con un carattere "�" (carattere di sostituzione U+FFFD) nella stringa di output. .NET Core 3.0 differisce dalle versioni precedenti di .NET Core e .NET Framework in quanto segue la procedura consigliata di Unicode che prevede di eseguire questa sostituzione durante l'operazione di transcodifica.
Questa modifica è parte di un'iniziativa più ampia volta a migliorare la gestione di UTF-8 in .NET, che include i nuovi tipi System.Text.Unicode.Utf8 e System.Text.Rune. Al tipo UTF8Encoding è stato assegnato un meccanismo di gestione degli errori migliorato, in modo che produca un output coerente con i nuovi tipi introdotti.
Descrizione delle modifiche
A partire da .NET Core 3.0, durante la transcodifica dei byte in caratteri, la classe UTF8Encoding sostituisce i caratteri in base alle procedure consigliate per il formato Unicode. Il meccanismo di sostituzione usato è descritto nel documento The Unicode Standard, Version 12.0, Sec. 3.9 (PDF) nell'intestazione intitolata U+FFFD Substitution of Maximal Subparts.
Questo comportamento si applica solo quando la sequenza di byte di input contiene dati UTF-8 in formato non corretto. Inoltre, se l'istanza di UTF8Encoding è stata costruita con throwOnInvalidBytes: true, l'istanza di UTF8Encoding continuerà a generare eccezioni di input non valido anziché eseguire la sostituzione con il carattere U+FFFD. Per altre informazioni sul costruttore UTF8Encoding, fai riferimento a UTF8Encoding(Boolean, Boolean).
La tabella seguente illustra l'impatto di questa modifica con un input a 3 byte non valido:
Input a 3 byte in formato non corretto
Output prima di .NET Core 3.0
Output a partire da .NET Core 3.0
[ ED A0 90 ]
[ FFFD FFFD ] (output di 2 caratteri)
[ FFFD FFFD FFFD ] (output di 3 caratteri)
L'output di 3 caratteri è l'output preferito secondo la Tabella 3-9 del PDF sullo standard Unicode indicato in precedenza.
Versione introdotta
3,0
Azione consigliata
Non è necessaria alcuna azione da parte dello sviluppatore.
In .NET Core 2.2 e versioni precedenti la classe TypeDescriptionProviderAttribute si trova nell'assembly System.ComponentModel.TypeConverter.
A partire da .NET Core 3.0, si trova nell'assembly System.ObjectModel.
Versione introdotta
3,0
Azione consigliata
Questa modifica influisce solo sulle applicazioni che usano la reflection per caricare il tipo TypeDescriptionProviderAttribute chiamando un metodo come Assembly.GetType o un overload di Activator.CreateInstance che presuppone che il tipo si trovi in un assembly specifico. In tal caso, l'assembly a cui viene fatto riferimento nella chiamata al metodo va aggiornato in modo da riflettere il nuovo percorso dell'assembly del tipo.
Category
WinForms
API interessate
Nessuno.
ZipArchiveEntry non gestisce più gli archivi con dimensioni delle voci incoerenti
Gli archivi ZIP elencano nella directory centrale e nell'intestazione locale sia le dimensioni compresse che le dimensioni non compresse. I dati stessi delle voci indicano anche le dimensioni. In .NET Core 2.2 e versioni precedenti, la coerenza di questi valori non veniva mai verificata. A partire da .NET Core 3.0 viene invece verificata.
Descrizione delle modifiche
In .NET Core 2.2 e versioni precedenti, ZipArchiveEntry.Open() ha esito positivo anche se l'intestazione locale non concorda con l'intestazione centrale del file ZIP. I dati vengono decompressi finché non viene raggiunta la fine del flusso compresso, anche se la sua lunghezza supera le dimensioni del file non compresso indicate nell'intestazione locale o nella directory centrale.
A partire da .NET Core 3.0, il metodo ZipArchiveEntry.Open() verifica che le dimensioni compresse e non compresse di una voce indicate nell'intestazione locale e nell'intestazione centrale coincidano. In caso contrario, il metodo genera un'eccezione InvalidDataException se l'intestazione locale dell'archivio e/o il descrittore dei dati elencano dimensioni delle voci discordanti rispetto alla directory centrale del file ZIP. Durante la lettura di una voce, i dati decompressi vengono troncati in corrispondenza delle dimensioni del file non compresso citate nell'intestazione.
Questa modifica è stata apportata per garantire che un elemento ZipArchiveEntry rappresenti correttamente le dimensioni dei suoi dati e che venga letta solo la quantità di dati indicata.
Versione introdotta
3,0
Azione consigliata
Ricrea il pacchetto di qualsiasi archivio ZIP che presenti questi problemi.
In .NET Framework e nelle versioni di .NET Core precedenti alla 3.0 è possibile impostare il valore di un campo statico costante dopo l'inizializzazione (readonly in C#) chiamando System.Reflection.FieldInfo.SetValue. Tuttavia, impostare un campo di questo tipo in questo modo produceva un comportamento imprevedibile in base al framework di destinazione e alle impostazioni di ottimizzazione.
Un campo InitOnly è un campo che può essere impostato solo nel momento in cui viene dichiarato o nel costruttore per la classe contenitore. In altre parole, è costante dopo l'inizializzazione.
Versione introdotta
3,0
Azione consigliata
Inizializza i campi InitOnly statici in un costruttore statico. Questo vale sia per i tipi dinamici, sia per quelli non dinamici.
Il passaggio di GroupCollection ai metodi di estensione che accettano IEnumerable<T> richiede la disambiguazione
Quando si chiama un metodo di estensione che accetta IEnumerable<T> su un elemento GroupCollection, è necessario eliminare le ambiguità in merito al tipo usando un cast.
Descrizione delle modifiche
A partire da .NET Core 3.0, System.Text.RegularExpressions.GroupCollection implementa IEnumerable<KeyValuePair<String,Group>> oltre agli altri tipi implementati, tra cui IEnumerable<Group>. Questo crea ambiguità quando si chiama un metodo di estensione che accetta un elemento IEnumerable<T>. Se si chiama tale metodo di estensione su un'istanza di GroupCollection, ad esempio Enumerable.Count, verrà visualizzato l'errore del compilatore seguente:
CS1061: 'GroupCollection' non contiene una definizione di 'Count' e non è stato trovato alcun metodo di estensione accessibile 'Count' che accetta un primo argomento di tipo 'GroupCollection'. Probabilmente manca una direttiva using o un riferimento all'assembly.
Nelle versioni precedenti di .NET non c'erano ambiguità né si verificavano errori del compilatore.
Versione introdotta
3,0
Motivo della modifica
Si tratta di una modifica che causa un'interruzione involontaria. Perché la situazione è così già da qualche tempo, non abbiamo intenzione di ripristinare il comportamento precedente. Inoltre, la modifica stessa sarebbe causa di interruzioni.
Azione consigliata
Per le istanze GroupCollection, disambigua le chiamate ai metodi di estensione che accettano un oggetto IEnumerable<T> con un cast.
// Without a cast - causes CS1061.
match.Groups.Count(_ => true)
// With a disambiguating cast.
((IEnumerable<Group>)m.Groups).Count(_ => true);
Category
Principali librerie .NET
API interessate
Qualsiasi metodo di estensione che accetta un elemento IEnumerable<T> è interessato. Ad esempio:
La sintassi "BEGIN TRUSTED CERTIFICATE" non è più supportata per i certificati radice in Linux
I certificati radice in Linux e in altri sistemi simili a Unix (ma non macOS) possono essere presentati in due forme: l'intestazione PEM BEGIN CERTIFICATE standard e l'intestazione PEM BEGIN TRUSTED CERTIFICATE specifica di OpenSSL. La seconda sintassi consente una configurazione aggiuntiva che ha causato problemi di compatibilità con la classe System.Security.Cryptography.X509Certificates.X509Chain di .NET Core. I contenuti del certificato radice BEGIN TRUSTED CERTIFICATE non vengono più caricati dal motore della catena a partire da .NET Core 3.0.
Descrizione delle modifiche
In precedenza, venivano usate entrambe le sintassi BEGIN CERTIFICATE e BEGIN TRUSTED CERTIFICATE per popolare l'elenco di attendibilità radice. Se veniva usata la sintassi BEGIN TRUSTED CERTIFICATE e venivano specificate opzioni aggiuntive nel file, era possibile che X509Chain segnalasse che la catena di attendibilità non era consentita in modo esplicito (X509ChainStatusFlags.ExplicitDistrust). Se tuttavia il certificato veniva specificato anche con la sintassi BEGIN CERTIFICATE in un file caricato in precedenza, la catena di attendibilità era consentita.
A partire da .NET Core 3.0, i contenuti di BEGIN TRUSTED CERTIFICATE non vengono più letti. Se il certificato non viene specificato anche tramite una sintassi BEGIN CERTIFICATE standard, X509Chain segnala che la radice non è attendibile (X509ChainStatusFlags.UntrustedRoot).
Versione introdotta
3,0
Azione consigliata
La maggior parte delle applicazioni non è interessata da questa modifica, ma le applicazioni che non possono visualizzare entrambe le origini di certificati radice a causa di problemi di autorizzazioni potrebbero rilevare errori di tipo UntrustedRoot imprevisti dopo l'aggiornamento.
Molte distribuzioni di Linux scrivono i certificati radice in due posizioni: una directory con un certificato per file e una concatenazione di un file. In alcune distribuzioni la directory con un certificato per file usa la sintassi BEGIN TRUSTED CERTIFICATE mentre la concatenazione dei file usa la sintassi BEGIN CERTIFICATE standard. Assicurarsi che tutti i certificati radice personalizzati vengano aggiunti come BEGIN CERTIFICATE in almeno una di queste posizioni e che entrambe le posizioni possano essere lette dall'applicazione.
La directory tipica è /etc/ssl/certs/ e il file concatenato tipico è /etc/ssl/cert.pem. Usare il comando openssl version -d per determinare la radice specifica della piattaforma, che può differire da /etc/ssl/. Ad esempio, in Ubuntu 18.04 la directory è /usr/lib/ssl/certs/ e il file è /usr/lib/ssl/cert.pem. Tuttavia, /usr/lib/ssl/certs/ è un collegamento simbolico per /etc/ssl/certs/ e /usr/lib/ssl/cert.pem non esiste.
$ openssl version -d
OPENSSLDIR: "/usr/lib/ssl"
$ ls -al /usr/lib/ssl
total 12
drwxr-xr-x 3 root root 4096 Dec 12 17:10 .
drwxr-xr-x 73 root root 4096 Feb 20 15:18 ..
lrwxrwxrwx 1 root root 14 Mar 27 2018 certs -> /etc/ssl/certs
drwxr-xr-x 2 root root 4096 Dec 12 17:10 misc
lrwxrwxrwx 1 root root 20 Nov 12 16:58 openssl.cnf -> /etc/ssl/openssl.cnf
lrwxrwxrwx 1 root root 16 Mar 27 2018 private -> /etc/ssl/private
EnvelopedCms usa per impostazione predefinita la crittografia AES-256
L'algoritmo di crittografia simmetrica predefinito usato da EnvelopedCms è passato da TripleDES ad AES-256.
Descrizione delle modifiche
Nelle versioni precedenti quando EnvelopedCms viene usato per crittografare i dati senza specificare un algoritmo di crittografia simmetrica tramite un overload del costruttore, i dati vengono crittografati con l'algoritmo TripleDES/3DES/3DEA/DES3-EDE.
A partire da .NET Core 3.0 (tramite la versione 4.6.0 del pacchetto NuGet System.Security.Cryptography.Pkcs), l'algoritmo predefinito è stato modificato in AES-256 per la modernizzazione dell'algoritmo e per migliorare la sicurezza delle opzioni predefinite. Se un certificato del destinatario del messaggio ha una chiave pubblica Diffie-Hellman (non EC), l'operazione di crittografia potrebbe non riuscire con un'eccezione CryptographicException a causa di limitazioni nella piattaforma sottostante.
Nel codice di esempio seguente i dati vengono crittografati con TripleDES in caso di esecuzione in .NET Core 2.2 o versioni precedenti. In caso di esecuzione in .NET Core 3.0 o versione successiva, vengono crittografati con AES-256.
EnvelopedCms cms = new EnvelopedCms(content);
cms.Encrypt(recipient);
return cms.Encode();
Versione introdotta
3,0
Azione consigliata
Se si è interessati negativamente dalla modifica, è possibile ripristinare la crittografia TripleDES specificando in modo esplicito l'identificatore dell'algoritmo di crittografia in un costruttore EnvelopedCms che include un parametro di tipo AlgorithmIdentifier, ad esempio:
Oid tripleDesOid = new Oid("1.2.840.113549.3.7", null);
AlgorithmIdentifier tripleDesIdentifier = new AlgorithmIdentifier(tripleDesOid);
EnvelopedCms cms = new EnvelopedCms(content, tripleDesIdentifier);
cms.Encrypt(recipient);
return cms.Encode();
Le dimensioni minime per la generazione di chiavi RSAOpenSsl sono aumentate
Le dimensioni minime per la generazione di nuove chiavi RSA in Linux sono aumentate da 384 bit a 512 bit.
Descrizione delle modifiche
A partire da .NET Core 3.0, le dimensioni minime valide per la chiave segnalate dalla proprietà LegalKeySizes nelle istanze di RSA da RSA.Create, RSAOpenSsl e RSACryptoServiceProvider in Linux sono aumentate da 384 a 512.
Di conseguenza, in .NET Core 2.2 e versioni precedenti una chiamata a un metodo come RSA.Create(384) ha esito positivo. In .NET Core 3.0 e versioni successive la chiamata al metodo RSA.Create(384) genera un'eccezione che indica che le dimensioni sono troppo piccole.
Questa modifica è stata apportata perché OpenSSL, che esegue le operazioni di crittografia in Linux, ha aumentato il valore minimo tra le versioni 1.0.2 e 1.1.0. .NET Core 3.0 preferisce OpenSSL 1.1.x a 1.0.x e la versione minima segnalata è stata aumentata per riflettere questa nuova limitazione di dipendenza superiore.
Versione introdotta
3,0
Azione consigliata
Se si chiama una delle API interessate, assicurarsi che le dimensioni di tutte le chiavi generate non siano inferiori al valore minimo del provider.
Nota
L'uso di RSA a 384 bit è già considerato non sicuro, così come RSA a 512 bit. Le raccomandazioni moderne, ad esempio la Pubblicazione speciale NIST 800-57 Parte 1 Revisione 4, suggeriscono 2048 bit come dimensione minima per le chiavi appena generate.
.NET Core 3.0 preferisce OpenSSL 1.1.x a OpenSSL 1.0.x
.NET Core per Linux, che funziona in più distribuzioni Linux, può supportare sia OpenSSL 1.0.x sia OpenSSL 1.1.x. .NET Core 2.1 e .NET Core 2.2 cercano prima 1.0.x, quindi eseguono il fallback a 1.1.x, mentre .NET Core 3.0 cerca prima 1.1.x. Questa modifica è stata apportata per aggiungere il supporto per i nuovi standard di crittografia.
Questa modifica può influire sulle librerie o sulle applicazioni che eseguono operazioni di interoperabilità della piattaforma con i tipi di interoperabilità specifici di OpenSSL in .NET Core.
Descrizione delle modifiche
In .NET Core 2.2 e versioni precedenti il runtime preferisce caricare OpenSSL 1.0.x piuttosto che 1.1.x. Ciò significa che i tipi IntPtr e SafeHandle per l'interoperabilità con OpenSSL vengono usati preferibilmente con libcrypto.so.1.0.0, libcrypto.so.1.0 o libcrypto.so.10.
A partire da .NET Core 3.0, il runtime preferisce caricare OpenSSL 1.1.x rispetto a OpenSSL 1.0.x, quindi i tipi IntPtr e SafeHandle per l'interoperabilità con OpenSSL vengono usati preferibilmente con libcrypto.so.1.1, libcrypto.so.11/libcrypto.so.1.1.0 o libcrypto.so.1.1.1. Di conseguenza, le librerie e le applicazioni che interagiscono direttamente con OpenSSL possono avere puntatori incompatibili con i valori esposti da .NET Core quando si esegue l'aggiornamento da .NET Core 2.1 o .NET Core 2.2.
Versione introdotta
3,0
Azione consigliata
Le librerie e le applicazioni che eseguono operazioni dirette con OpenSSL devono prestare attenzione per assicurarsi di usare la stessa versione di OpenSSL del runtime di .NET Core.
Tutte le librerie o le applicazioni che usano i valori IntPtr o SafeHandle dei tipi di crittografia .NET Core direttamente con OpenSSL devono confrontare la versione della libreria usata con la nuova proprietà SafeEvpPKeyHandle.OpenSslVersion per garantire che i puntatori siano compatibili.
CryptoStream.Dispose trasforma il blocco finale solo durante la scrittura
Il metodo CryptoStream.Dispose, usato per completare operazioni CryptoStream, non prova più a trasformare il blocco finale durante la lettura.
Descrizione delle modifiche
Nelle versioni precedenti di .NET se un utente eseguiva una lettura incompleta durante l'uso di CryptoStream in modalità Read, era possibile che il metodo Dispose generasse un'eccezione, ad esempio quando si usava AES con riempimento. L'eccezione veniva generata perché veniva eseguito un tentativo di trasformare il blocco finale ma i dati erano incompleti.
In .NET Core 3.0 e versioni successive Dispose non prova più a trasformare il blocco finale durante la lettura, consentendo quindi letture incomplete.
Motivo della modifica
Questa modifica consente letture incomplete dal flusso di crittografia quando un'operazione di rete viene annullata, senza la necessità di intercettare un'eccezione.
Versione introdotta
3,0
Azione consigliata
La maggior parte delle app non dovrebbe essere interessata da questa modifica.
Se l'applicazione ha intercettato in precedenza un'eccezione in caso di lettura incompleta, è possibile eliminare tale blocco catch.
Se l'app ha usato la trasformazione del blocco finale negli scenari di hashing, potrebbe essere necessario assicurarsi che l'intero flusso venga letto prima dell'eliminazione.
Le impostazioni locali "C" sono mappate alle impostazioni locali invarianti
.NET Core 2.2 e versioni precedenti dipendono dal comportamento di ICU predefinito, che esegue il mapping delle impostazioni locali "C" alle impostazioni locali en_US_POSIX. Le impostazioni locali en_US_POSIX hanno un comportamento indesiderato delle regole di confronto, perché non supporta confronti tra stringhe senza distinzione tra maiuscole e minuscole. Poiché alcune distribuzioni Linux impostano le impostazioni locali "C" come impostazioni locali predefinite, gli utenti riscontravano un comportamento imprevisto.
Descrizione delle modifiche
A partire da .NET Core 3.0, il mapping delle impostazioni locali "C" è stato modificato per usare le impostazioni locali invarianti anziché en_US_POSIX. Anche le impostazioni locali "C" al mapping invariante vengono applicate a Windows per la coerenza.
Il mapping di "C" alle impostazioni cultura en_US_POSIX causava confusione del cliente, perché en_US_POSIX non supporta operazioni di ordinamento/ricerca di stringhe senza distinzione tra maiuscole e minuscole. Poiché le impostazioni locali "C" vengono usate come impostazioni locali predefinite in alcune delle distribuzioni Linux, i clienti hanno riscontrato questo comportamento indesiderato in questi sistemi operativi.
Versione introdotta
3,0
Azione consigliata
Niente di più specifico della consapevolezza di questo cambiamento. Questa modifica influisce solo sulle applicazioni che usano il mapping delle impostazioni locali "C".
Category
Globalizzazione
API interessate
Tutte le API delle regole di confronto e delle impostazioni cultura sono interessate da questa modifica.
A partire da .NET Core 3.0, nel caso predefinito MSBuild genera un nome file manifesto diverso per i file di risorse.
Versione di introduzione
3,0
Descrizione delle modifiche
Prima di .NET Core 3.0, se non venivano specificati metadati per LogicalName, ManifestResourceName o DependentUpon per un elemento EmbeddedResource nel file di progetto, MSBuild generava un nome file manifesto nel modello <RootNamespace>.<ResourceFilePathFromProjectRoot>.resources. Se RootNamespace non è definito nel file di progetto, per impostazione predefinita viene impostato sul nome del progetto. Ad esempio, il nome del manifesto generato per un file di risorse denominato Form1.resx nella directory del progetto radice era MyProject.Form1.resources.
A partire da .NET Core 3.0, se un file di risorse condivide il percorso con un file di origine con lo stesso nome, ad esempio, Form1.resx e Form1.cs, MSBuild usa le informazioni sul tipo dal file di origine per generare il nome file manifesto nel modello <Namespace>.<ClassName>.resources. Lo spazio dei nomi e il nome della classe vengono estratti dal primo tipo nel file di origine con percorso condiviso. Ad esempio, il nome del manifesto generato per un file di risorse denominato Form1.resx che condivide il percorso con un file di origine denominato Form1.cs è MyNamespace.Form1.resources. L'aspetto principale da notare è che la prima parte del nome file è diversa dalle versioni precedenti di .NET Core, ovvero MyNamespace anziché MyProject.
Nota
Se nel file di progetto sono stati specificati metadati per LogicalName, ManifestResourceName o DependentUpon in un elemento EmbeddedResource, questa modifica non influisce sul file di risorse.
Questa modifica che causa un'interruzione è stata introdotta con l'aggiunta della proprietà EmbeddedResourceUseDependentUponConvention ai progetti .NET Core. Per impostazione predefinita, i file di risorse non sono elencati in modo esplicito in un file di progetto di .NET Core, pertanto non hanno metadati DependentUpon per specificare come assegnare un nome al file con estensione resources generato. Quando EmbeddedResourceUseDependentUponConvention è impostato su true, ovvero l'impostazione predefinita, MSBuild cerca un file di origine con percorso condiviso ed estrae uno spazio dei nomi e un nome di classe da tale file. Se si imposta EmbeddedResourceUseDependentUponConvention su false, MSBuild genera il nome del manifesto in base al comportamento precedente, che combina RootNamespace e il percorso del file relativo.
Azione consigliata
Nella maggior parte dei casi non è necessaria alcuna azione da parte dello sviluppatore e l'app dovrebbe continuare a funzionare. Se tuttavia questa modifica causa interruzioni nell'app, è possibile:
Modificare il codice in modo da prevedere il nuovo nome del manifesto.
Rifiutare esplicitamente la nuova convenzione di denominazione impostando EmbeddedResourceUseDependentUponConvention su false nel file di progetto.
In .NET Core da 1.0 a 2.0, il valore predefinito della proprietà System.Net.Http.HttpRequestMessage.Version è 1.1. A partire da .NET Core 2.1, è stato modificato in 2.1.
Comportamento di trascinamento della selezione modificato nelle editor di testo
.NET Core 3.0 ha introdotto una modifica del modo in cui i controlli dell'editor di testo creano un System.Windows.DataObject oggetto quando si trascina il testo in un altro controllo. Modifica della conversione automatica disabilitata, causando l'operazione di mantenere i dati come DataFormats.Text o DataFormats.UnicodeText invece di convertirli in DataFormats.StringFormat.
L'origine di questo contenuto è disponibile in GitHub, in cui è anche possibile creare ed esaminare i problemi e le richieste pull. Per ulteriori informazioni, vedere la guida per i collaboratori.
Feedback su .NET
.NET è un progetto di open source. Selezionare un collegamento per fornire feedback: