Eseguire la migrazione da ASP.NET Core 2.2 a 3.0
Di Scott Addie e Rick Anderson
Questo articolo illustra come aggiornare un progetto ASP.NET Core 2.2 esistente a ASP.NET Core 3.0. Potrebbe essere utile creare un nuovo progetto ASP.NET Core 3.0 per:
- Confrontare con il codice ASP.NET Core 2.2.
- Copiare le modifiche pertinenti nel progetto ASP.NET Core 3.0.
Prerequisiti
- Visual Studio 2019 con il carico di lavoro Sviluppo ASP.NET e Web
- .NET Core 3.0 SDK
Aggiornare la versione di .NET Core SDK in global.json
Se la soluzione si basa su un global.json file per specificare una versione specifica di .NET Core SDK, aggiornarne version
la proprietà alla versione 3.0 installata nel computer:
{
"sdk": {
"version": "3.0.100"
}
}
Aggiornare il file di progetto
Aggiornare il framework di destinazione
ASP.NET Core 3.0 e versioni successive vengono eseguiti solo in .NET Core. Imposta il Moniker Framework di Destinazione (TFM) su netcoreapp3.0
:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
</Project>
Rimuovere i riferimenti ai pacchetti obsoleti
Un numero elevato di pacchetti NuGet non viene prodotto per ASP.NET Core 3.0. Tali riferimenti al pacchetto devono essere rimossi dal file di progetto. Si consideri il file di progetto seguente per un'app Web ASP.NET Core 2.2:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App"/>
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
</Project>
File di progetto aggiornato per ASP.NET Core 3.0:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
</Project>
File di progetto ASP.NET Core 3.0 aggiornato:
Nel
<PropertyGroup>
:- Aggiorna TFM a
netcoreapp3.0
- Rimuove l'elemento
<AspNetCoreHostingModel>
. Per ulteriori informazioni, vedere Modello di hosting in-process in questo documento.
- Aggiorna TFM a
In
<ItemGroup>
-
Microsoft.AspNetCore.App
viene rimosso. Per altre informazioni, vedere Informazioni di riferimento sul framework in questo documento. -
Microsoft.AspNetCore.Razor.Design
viene rimosso e fa parte del seguente elenco di pacchetti che non vengono più prodotti.
-
Per visualizzare l'elenco completo dei pacchetti non più prodotti, selezionare l'elenco di espansione seguente:
Fare clic per espandere l'elenco dei pacchetti non più prodotti
- Microsoft.AspNetCore
- Microsoft.AspNetCore.All
- Microsoft.AspNetCore.App
- Microsoft.AspNetCore.Antiforgery
- Microsoft.AspNetCore.Authentication
- Microsoft.AspNetCore.Authentication.Abstractions
- Microsoft.AspNetCore.Authentication.Cookies
- Microsoft.AspNetCore.Authentication.Core
- Microsoft.AspNetCore.Authentication.OAuth
- Microsoft.AspNetCore.Authorization.Policy
- Microsoft.AspNetCore.CookiePolicy
- Microsoft.AspNetCore.Cors
- Microsoft.AspNetCore.Diagnostics
- Microsoft.AspNetCore.Diagnostics.HealthChecks
- Microsoft.AspNetCore.HostFiltering
- Microsoft.AspNetCore.Hosting
- Microsoft.AspNetCore.Hosting.Abstractions
- Microsoft.AspNetCore.Hosting.Server.Abstractions
- Microsoft.AspNetCore.Http
- Microsoft.AspNetCore.Http.Abstractions
- Microsoft.AspNetCore.Http.Connections
- Microsoft.AspNetCore.Http.Extensions
- Microsoft.AspNetCore.HttpOverrides
- Microsoft.AspNetCore.HttpsPolicy
- Microsoft.AspNetCore.Identity
- Microsoft.AspNetCore.Localization
- Microsoft.AspNetCore.Localization.Routing
- Microsoft.AspNetCore.Mvc
- Microsoft.AspNetCore.Mvc.Abstractions
- Microsoft.AspNetCore.Mvc.Analyzers
- Microsoft.AspNetCore.Mvc.ApiExplorer
- Microsoft.AspNetCore.Mvc.Api.Analyzers
- Microsoft.AspNetCore.Mvc.Core
- Microsoft.AspNetCore.Mvc.Cors
- Microsoft.AspNetCore.Mvc.DataAnnotations
- Microsoft.AspNetCore.Mvc.Formatters.Json
- Microsoft.AspNetCore.Mvc.Formatters.Xml
- Microsoft.AspNetCore.Mvc.Localization
- Microsoft.AspNetCore.Mvc.Razor
- Microsoft.AspNetCore.Mvc.Razor.ViewCompilation
- Microsoft.AspNetCore.Mvc.RazorPages
- Microsoft.AspNetCore.Mvc.TagHelpers
- Microsoft.AspNetCore.Mvc.ViewFeatures
- Microsoft.AspNetCore.Razor
- Microsoft.AspNetCore.Razor. Runtime
- Microsoft.AspNetCore.Razor.Design
- Microsoft.AspNetCore.ResponseCaching
- Microsoft.AspNetCore.ResponseCaching.Abstractions
- Microsoft.AspNetCore.ResponseCompression
- Microsoft.AspNetCore.Rewrite
- Microsoft.AspNetCore.Routing
- Microsoft.AspNetCore.Routing.Abstractions
- Microsoft.AspNetCore.Server.HttpSys
- Microsoft.AspNetCore.Server.IIS
- Microsoft.AspNetCore.Server.IISIntegration
- Microsoft.AspNetCore.Server.Kestrel
- Microsoft.AspNetCore.Server.Kestrel.Core
- Microsoft.AspNetCore.Server.Kestrel. Https
- Microsoft.AspNetCore.Server.Kestrel. Transport.Abstractions
- Microsoft.AspNetCore.Server.Kestrel. Transport.Sockets
- Microsoft.AspNetCore.Session
- Microsoft.AspNetCore.SignalR
- Microsoft.AspNetCore.SignalR.Core
- Microsoft.AspNetCore.StaticFiles
- Microsoft.AspNetCore.WebSockets
- Microsoft.AspNetCore.WebUtilities
- Microsoft.Net.Http.Headers
Rivedere le modifiche che causano un'interruzione
Rivedere le modifiche critiche
Informazioni di riferimento sul framework
Le funzionalità di ASP.NET Core disponibili tramite uno dei pacchetti elencati in precedenza sono disponibili come parte del Microsoft.AspNetCore.App
framework condiviso. Il framework condiviso è il set di assembly (file .dll ) installati nel computer e include un componente di runtime e un pacchetto di destinazione. Per altre informazioni, vedere The shared framework (Il framework condiviso).
I progetti destinati all'SDK
Microsoft.NET.Sdk.Web
fanno riferimento in modo implicito alMicrosoft.AspNetCore.App
framework.Per questi progetti non sono necessari riferimenti aggiuntivi:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> ... </Project>
I progetti che mirano a
Microsoft.NET.Sdk
oMicrosoft.NET.Sdk.Razor
SDK, dovrebbero aggiungere una definizione esplicita diFrameworkReference
aMicrosoft.AspNetCore.App
:<Project Sdk="Microsoft.NET.Sdk.Razor"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> <ItemGroup> <FrameworkReference Include="Microsoft.AspNetCore.App" /> </ItemGroup> ... </Project>
Compilazioni dipendenti dal framework con Docker
Le build dipendenti dal framework delle app console che usano un pacchetto che dipende dal framework condiviso di ASP.NET Core possono restituire l'errore di runtime seguente:
It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '3.0.0' was not found.
- No frameworks were found.
Microsoft.AspNetCore.App
è il framework condiviso contenente il runtime di ASP.NET Core ed è presente solo nell'immagine dotnet/core/aspnet
Docker. L'SDK 3.0 riduce le dimensioni delle compilazioni dipendenti dal framework usando ASP.NET Core senza includere copie duplicate delle librerie disponibili nel framework condiviso. Si tratta di un potenziale risparmio di fino a 18 MB, ma richiede che il runtime di ASP.NET Core sia presente/installato per eseguire l'app.
Per determinare se l'app ha una dipendenza (diretta o indiretta) nel framework condiviso ASP.NET Core, esaminare il runtimeconfig.json
file generato durante una compilazione/pubblicazione dell'app. Il file JSON seguente mostra una dipendenza dal framework condiviso ASP.NET Core:
{
"runtimeOptions": {
"tfm": "netcoreapp3.0",
"framework": {
"name": "Microsoft.AspNetCore.App",
"version": "3.0.0"
},
"configProperties": {
"System.GC.Server": true
}
}
}
Se l'app usa Docker, usare un'immagine di base che include ASP.NET Core 3.0. Ad esempio: docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0
.
Aggiungere riferimenti ai pacchetti per gli assembly rimossi
ASP.NET Core 3.0 rimuove alcuni assembly che in precedenza facevano parte del riferimento al Microsoft.AspNetCore.App
pacchetto. Per visualizzare gli assembly rimossi, confrontare le due cartelle del framework condiviso. Ad esempio, un confronto tra le versioni 2.2.7 e 3.0.0:
Per continuare a usare le funzionalità fornite dagli assembly rimossi, fare riferimento alle versioni 3.0 dei pacchetti corrispondenti:
Un'app Web generata da modelli con account utente singoli richiede l'aggiunta dei pacchetti seguenti:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> <UserSecretsId>My-secret</UserSecretsId> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0" /> </ItemGroup> </Project>
-
Per ulteriori informazioni su come fare riferimento al pacchetto specifico del provider di database, vedere Provider di Database.
Identity Interfaccia Utente
Il supporto per Identity l'interfaccia utente può essere aggiunto facendo riferimento al pacchetto Microsoft.AspNetCore.Identity.UI.
Servizi SPA
Autenticazione: il supporto per i flussi di autenticazione di terze parti è disponibile come pacchetti NuGet:
- Facebook OAuth (Microsoft.AspNetCore.Authentication.Facebook)
- Google OAuth (Microsoft.AspNetCore.Authentication.Google)
- Autenticazione dell'account Microsoft (Microsoft.AspNetCore.Authentication.MicrosoftAccount)
- Autenticazione OpenID Connect (Microsoft.AspNetCore.Authentication.OpenIdConnect)
- Token di connessione OpenID Connect (Microsoft.AspNetCore.Authentication.JwtBearer)
- Twitter OAuth (Microsoft.AspNetCore.Authentication.Twitter)
- Autenticazione WsFederation (Microsoft.AspNetCore.Authentication.WsFederation)
Supporto per la formattazione e la negoziazione del contenuto per
System.Net.HttpClient
: il pacchetto NuGet Microsoft.AspNet.WebApi.Client offre un'estendibilità utile aSystem.Net.HttpClient
con API comeReadAsAsync
ePostJsonAsync
. Tuttavia, questo pacchetto dipende daNewtonsoft.Json
, non daSystem.Text.Json
. Ciò significa che, ad esempio, i nomi delle proprietà di serializzazione specificati daJsonPropertyNameAttribute
(System.Text.Json
) vengono ignorati. È disponibile un pacchetto NuGet più recente che contiene metodi di estensione simili, ma usaSystem.Text.Json
: System.Net.Http.Json.Razor compilazione in fase di esecuzione: il supporto per la compilazione in fase di esecuzione di Razor visualizzazioni e pagine fa ora parte di Microsoft.AspNetCore.Mvc.Razor. RuntimeCompilation.
Supporto di MVC
Newtonsoft.Json
(Json.NET): il supporto per l'uso di MVC conNewtonsoft.Json
è ora incluso inMicrosoft.AspNetCore.Mvc.NewtonsoftJson
.
Modifiche alla startup
L'immagine seguente mostra le righe eliminate e modificate in un'app Web ASP.NET Core 2.2 Razor Pages:
Nell'immagine precedente il codice eliminato viene visualizzato in rosso. Il codice eliminato non mostra cookie il codice delle opzioni, che è stato eliminato prima di confrontare i file.
L'immagine seguente mostra le righe aggiunte e modificate in un'app Web ASP.NET Core 3.0 Razor Pages:
Nell'immagine precedente viene visualizzato il codice aggiunto in verde. Per informazioni sulle modifiche seguenti:
-
services.AddMvc
perservices.AddRazorPages
, vedere registrazione del servizio MVC in questo documento. -
CompatibilityVersion
, vedere Versione di compatibilità per ASP.NET Core MVC. -
IHostingEnvironment
perIWebHostEnvironment
, vedere questo annuncio di GitHub. -
app.UseAuthorization
è stato aggiunto ai modelli per mostrare che il middleware di autorizzazione dell'ordine deve essere aggiunto. Se l'app non usa l'autorizzazione, è possibile rimuovere in modo sicuro la chiamata aapp.UseAuthorization
. -
app.UseEndpoints
, vedere Razor Pages or Migrate Startup.Configure in questo documento.
Supporto analizzatore
Progetti che hanno come target Microsoft.NET.Sdk.Web
fanno riferimento implicitamente agli analizzatori precedentemente forniti come parte del pacchetto Microsoft.AspNetCore.Mvc.Analyzers. Non sono necessari riferimenti aggiuntivi per abilitarli.
Se la tua applicazione utilizza analizzatori API precedentemente forniti tramite il pacchetto Microsoft.AspNetCore.Mvc.Api.Analyzers, modifichi il file di progetto per fare riferimento agli analizzatori forniti come parte del .NET Core Web SDK.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
</PropertyGroup>
...
</Project>
Razor Libreria di classi
Razor I progetti di libreria di classi che forniscono componenti dell'interfaccia utente per MVC devono impostare la AddRazorSupportForMvc
proprietà nel file di progetto:
<PropertyGroup>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>
Modello di hosting in-process
Per impostazione predefinita, i progetti utilizzano il modello di hosting in-process in ASP.NET Core 3.0 o versione successiva. Facoltativamente, è possibile rimuovere la <AspNetCoreHostingModel>
proprietà nel file di progetto se il relativo valore è InProcess
.
Kestrel
Impostazione
Eseguire la migrazione della Kestrel configurazione al generatore host Web fornito da ConfigureWebHostDefaults
(Program.cs
):
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(serverOptions =>
{
// Set properties and call methods on options
})
.UseStartup<Startup>();
});
Se l'app crea manualmente l'host con ConfigureWebHost
anziché ConfigureWebHostDefaults
, chiamare UseKestrel
sul generatore di host Web.
public static void Main(string[] args)
{
var host = new HostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureWebHost(webBuilder =>
{
webBuilder.UseKestrel(serverOptions =>
{
// Set properties and call methods on options
})
.UseIISIntegration()
.UseStartup<Startup>();
})
.Build();
host.Run();
}
Il middleware di connessione sostituisce gli adattatori di connessione
Gli adattatori di connessione (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter
) sono stati rimossi da Kestrel. Sostituire gli adattatori di connessione con il middleware di connessione. Il middleware di connessione è simile al middleware HTTP nella pipeline ASP.NET Core, ma per le connessioni di livello inferiore. Registrazione di HTTPS e delle connessioni
- Sono stati spostati dagli adattatori di connessione al middleware di connessione.
- Questi metodi di estensione funzionano come nelle versioni precedenti di ASP.NET Core.
Per altre informazioni, vedere Kestrel.
Astrazioni di trasporto spostate e rese pubbliche
Il Kestrel livello di trasporto è stato esposto come interfaccia pubblica in Connections.Abstractions
. Una delle parti di questi aggiornamenti:
-
Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions
e i tipi associati sono stati rimossi. - NoDelay è stato spostato da ListenOptions alle opzioni di trasporto.
-
Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode
è stato rimosso da KestrelServerOptions.
Per altre informazioni, vedere le risorse di GitHub seguenti:
- Astrazioni di rete client/server (dotnet/AspNetCore #10308)
- Implementare una nuova astrazione per il listener bedrock e riposizionare Kestrel in cima (dotnet/AspNetCore #10321)
Kestrel Intestazioni trailer di richiesta
Per le app destinate a versioni precedenti di ASP.NET Core:
- Kestrel aggiunge intestazioni trailer in blocchi HTTP/1.1 nella raccolta di intestazioni della richiesta.
- I trailer sono disponibili dopo che l'intero corpo della richiesta è stato letto fino alla fine.
Ciò causa alcune preoccupazioni sull'ambiguità tra intestazioni e trailer, quindi i trailer sono stati spostati in una nuova raccolta (RequestTrailerExtensions
) nella versione 3.0.
I trailer delle richieste HTTP/2 sono:
- Non disponibile in ASP.NET Core 2.2.
- Disponibile nella versione 3.0 come
RequestTrailerExtensions
.
Per accedere a questi trailer sono presenti nuovi metodi di estensione delle richieste. Come per HTTP/1.1, i trailer sono disponibili dopo che il corpo della richiesta viene letto completamente.
Per la versione 3.0 sono disponibili i metodi seguenti RequestTrailerExtensions
:
-
GetDeclaredTrailers
: ottiene l'intestazione della richiestaTrailer
che elenca i trailer attesi dopo il corpo del messaggio. -
SupportsTrailers
: indica se la richiesta supporta la ricezione di intestazioni trailer. -
CheckTrailersAvailable
: Controlla se la richiesta supporta i trailer e se sono disponibili per essere letti. Questo controllo non presuppone che ci siano delle anteprime da leggere. Potrebbero non esserci trailer da visualizzare anche setrue
viene restituito da questo metodo. -
GetTrailer
: ottiene l'intestazione di coda richiesta dalla risposta. ControllareSupportsTrailers
prima di chiamareGetTrailer
, altrimenti potrebbe verificarsi un NotSupportedException se la richiesta non supporta le intestazioni di chiusura.
Per altre informazioni, vedere Inserire trailer delle richieste in una raccolta separata (dotnet/AspNetCore #10410).
AllowSynchronousIO disabilitato
AllowSynchronousIO
abilita o disabilita le API di I/O sincrone, ad esempio HttpRequest.Body.Read
, HttpResponse.Body.Write
e Stream.Flush
. Queste API sono una causa di esaurimento di thread che porta a crash delle applicazioni. Nella versione 3.0, AllowSynchronousIO
è disabilitato per impostazione predefinita. Per altre informazioni, vedere la sezione I/O sincrona nell'articoloKestrel.
Se è necessario un I/O sincrono, può essere abilitato configurando l'opzione AllowSynchronousIO
nel server in uso (quando si chiama ConfigureKestrel
, ad esempio, se si usa Kestrel). Si noti che i server (KestrelHttpSys, TestServer e così via) hanno tutte la propria AllowSynchronousIO
opzione che non influisce sugli altri server. Le operazioni di I/O sincrone possono essere abilitate per tutti i server in base alle richieste usando l'opzione IHttpBodyControlFeature.AllowSynchronousIO
:
var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
syncIOFeature.AllowSynchronousIO = true;
}
Se riscontri problemi con le TextWriter implementazioni o altri flussi che chiamano API sincrone in Dispose, chiama altrimenti la nuova DisposeAsync API.
Per altre informazioni, vedere [Annuncio] AllowSynchronousIO disabilitato in tutti i server (dotnet/AspNetCore #7644)..
Buffer del formattatore di output
I formattatori di output basati su Newtonsoft.JsonXmlSerializer, e DataContractSerializer supportano solo la serializzazione sincrona. Per consentire a questi formattatori di funzionare con le restrizioni AllowSynchronousIO del server, MVC memorizza nel buffer l'output di questi formattatori prima di scrivere su disco. In seguito al buffering, MVC includerà l'intestazione Content-Length quando risponde utilizzando questi formattatori.
System.Text.Json supporta la serializzazione asincrona e di conseguenza il formattatore basato su System.Text.Json
non esegue il buffering. Prendere in considerazione l'uso di questo formattatore per migliorare le prestazioni.
Per disabilitare il buffering, le applicazioni possono configurare SuppressOutputFormatterBuffering nell'avvio:
services.AddControllers(options => options.SuppressOutputFormatterBuffering = true)
Si noti che questo può comportare il lancio di un'eccezione di runtime se AllowSynchronousIO
non è anche configurato.
Microsoft.AspNetCore.Server.Kestrel.HTTPS assembly rimosso
In ASP.NET Core 2.1, il contenuto di Microsoft.AspNetCore.Server.Kestrel. Https.dll sono stati spostati in Microsoft.AspNetCore.Server.Kestrel. Core.dll. Si tratta di un aggiornamento non distruttivo che utilizza attributi TypeForwardedTo
. Per la versione 3.0, l'assembly Microsoft.AspNetCore.Server.Https.dll vuoto e il pacchetto NuGet sono stati rimossi.
Librerie che fanno riferimento a Microsoft.AspNetCore.Server.Kestrel. Https devono aggiornare le dipendenze di ASP.NET Core alla versione 2.1 o successiva.
Le app e le librerie destinate a ASP.NET Core 2.1 o versione successiva devono rimuovere i riferimenti diretti al pacchetto Microsoft.AspNetCore.Server.Kestrel.Https.
Supporto di Newtonsoft.Json (Json.NET)
Come parte del lavoro per migliorare il framework condiviso ASP.NET Core, Newtonsoft.Json (Json.NET) è stato rimosso dal framework condiviso di ASP.NET Core.
Il serializzatore JSON predefinito per ASP.NET Core è ora System.Text.Json, che è una novità di .NET Core 3.0. Si consiglia di utilizzare System.Text.Json
quando possibile. È ad alte prestazioni e non richiede una libreria aggiuntiva. Tuttavia, poiché System.Text.Json
è una novità, potrebbe non essere presente alcuna funzionalità necessaria per l'app. Per altre informazioni, vedere Come eseguire la migrazione da Newtonsoft.Json a System.Text.Json.
Usare Newtonsoft.Json in un progetto ASP.NET Core 3.0 SignalR
Installare il pacchetto NuGet Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.
Sul client, effettuare una chiamata al metodo concatenato all'istanza
HubConnectionBuilder
:new HubConnectionBuilder() .WithUrl("/chathub") .AddNewtonsoftJsonProtocol(...) .Build();
Sul server, concatenare la chiamata al metodo
AddNewtonsoftJsonProtocol
alla chiamata al metodoAddSignalR
inStartup.ConfigureServices
:services.AddSignalR() .AddNewtonsoftJsonProtocol(...);
Usare Newtonsoft.Json in un progetto MVC ASP.NET Core 3.0
Installare il pacchetto
Microsoft.AspNetCore.Mvc.NewtonsoftJson
.Aggiornare
Startup.ConfigureServices
per chiamareAddNewtonsoftJson
.services.AddMvc() .AddNewtonsoftJson();
AddNewtonsoftJson
è compatibile con i nuovi metodi di registrazione del servizio MVC:AddRazorPages
AddControllersWithViews
AddControllers
services.AddControllers() .AddNewtonsoftJson();
Newtonsoft.Json
le impostazioni possono essere impostate nella chiamata aAddNewtonsoftJson
:services.AddMvc() .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
Nota: se il
AddNewtonsoftJson
metodo non è disponibile, assicurarsi di aver installato ilMicrosoft.AspNetCore.Mvc.NewtonsoftJson
pacchetto. Un errore comune consiste nell'installare il pacchetto Newtonsoft.Json anziché ilMicrosoft.AspNetCore.Mvc.NewtonsoftJson
pacchetto.
Per altre informazioni, vedere Aggiungere il supporto del formato JSON basato su Newtonsoft.Json.
Registrazione del servizio MVC
ASP.NET Core 3.0 aggiunge nuove opzioni per la registrazione di scenari MVC all'interno Startup.ConfigureServices
di .
Sono disponibili tre nuovi metodi di estensione di primo livello correlati agli scenari MVC.IServiceCollection
I modelli usano questi nuovi metodi anziché AddMvc
. Tuttavia, AddMvc
continua a comportarsi come nelle versioni precedenti.
Nell'esempio seguente viene aggiunto il supporto per i controller e le funzionalità correlate all'API, ma non per le visualizzazioni o le pagine. Il modello di API usa questo codice:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
Nell'esempio seguente viene aggiunto il supporto per controller, funzionalità correlate all'API e visualizzazioni, ma non per pagine. Il modello Applicazione Web (MVC) usa questo codice:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
Nell'esempio seguente viene aggiunto il supporto per Razor Pages e il supporto minimo del controller. Il modello Applicazione Web usa questo codice:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
È anche possibile combinare i nuovi metodi. L'esempio seguente equivale a chiamare AddMvc
in ASP.NET Core 2.2:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
}
Codice di avvio del routing
Se un'app chiama UseMvc
o UseSignalR
, migrare l'app a Endpoint Routing, se possibile. Per migliorare la compatibilità del routing degli endpoint con le versioni precedenti di MVC, sono state ripristinate alcune delle modifiche apportate alla generazione di URL introdotte in ASP.NET Core 2.2. Se si verificano problemi durante l'uso del routing degli endpoint nella versione 2.2, si prevedono miglioramenti in ASP.NET Core 3.0 con le eccezioni seguenti:
- Se l'app implementa
IRouter
o eredita daRoute
, usare DynamicRouteValuesTransformer come sostituzione. - Se l'app accede
RouteData.Routers
direttamente all'interno di MVC per analizzare gli URL, è possibile sostituirla con l'uso di LinkParser.ParsePathByEndpointName.- Definire il percorso con un nome di percorso.
- Usare
LinkParser.ParsePathByEndpointName
e passare il nome di route desiderato.
Il routing degli endpoint supporta la stessa sintassi del modello di route e le stesse funzionalità di creazione di modelli di route di IRouter
. Il routing degli endpoint supporta IRouteConstraint
. Il routing degli endpoint supporta [Route]
, [HttpGet]
e gli altri attributi di routing MVC.
Per la maggior parte delle applicazioni, sono necessarie solo Startup
modifiche.
Eseguire la migrazione di Startup.Configure
Consigli generali:
Aggiungere
UseRouting
.Se l'app chiama
UseStaticFiles
, posizionareUseStaticFiles
prima diUseRouting
.Se l'app utilizza funzionalità di autenticazione/autorizzazione come
AuthorizePage
o[Authorize]
, inserire la chiamata aUseAuthentication
eUseAuthorization
: dopo,UseRouting
eUseCors
, ma prima diUseEndpoints
.public void Configure(IApplicationBuilder app) { ... app.UseStaticFiles(); app.UseRouting(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
Sostituire
UseMvc
oUseSignalR
conUseEndpoints
.Se l'applicazione utilizza scenari CORS, come
[EnableCors]
, posizionare la chiamata aUseCors
prima di qualsiasi altro middleware che utilizza CORS (ad esempio, posizionareUseCors
prima diUseAuthentication
,UseAuthorization
eUseEndpoints
).Sostituire
IHostingEnvironment
conIWebHostEnvironment
e aggiungere un'istruzioneusing
per lo spazio dei nomi Microsoft.AspNetCore.Hosting.Sostituire
IApplicationLifetime
con IHostApplicationLifetime (Microsoft.Extensions.Hosting spazio dei nomi).Sostituire
EnvironmentName
con Environments (Microsoft.Extensions.Hosting spazio dei nomi).
Il codice seguente è un esempio di Startup.Configure
in una tipica app ASP.NET Core 2.2:
public void Configure(IApplicationBuilder app)
{
...
app.UseStaticFiles();
app.UseAuthentication();
app.UseSignalR(hubs =>
{
hubs.MapHub<ChatHub>("/chat");
});
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}
Dopo aver aggiornato il codice precedente Startup.Configure
:
public void Configure(IApplicationBuilder app)
{
...
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chat");
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}
Avviso
Per la maggior parte delle app, le chiamate a UseAuthentication
, UseAuthorization
e UseCors
devono essere visualizzate tra le chiamate a UseRouting
e UseEndpoints
per essere efficaci.
Controlli di integrità
I controlli di integrità utilizzano il routing degli endpoint con l'host generico. In Startup.Configure
chiamare MapHealthChecks
sul generatore di endpoint con l'URL dell'endpoint o il percorso relativo:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
Gli endpoint dei controlli di integrità possono:
- Specificare uno o più host/porte consentiti.
- Richiedere l'autorizzazione.
- È necessario abilitare CORS.
Per altre informazioni, vedere Controlli di integrità in ASP.NET Core.
Indicazioni sul middleware per la sicurezza
Il supporto per l'autorizzazione e per CORS è unificato attorno all'approccio middleware. In questo modo è possibile usare lo stesso middleware e funzionalità in questi scenari. In questa versione viene fornito un middleware di autorizzazione aggiornato e il middleware CORS è migliorato in modo da poter comprendere gli attributi usati dai controller MVC.
Condivisione delle Risorse tra Origini Diverse (CORS)
In precedenza, CORS potrebbe essere difficile da configurare. Il middleware è stato fornito per l'uso in alcuni casi d'uso, ma i filtri MVC erano destinati all'uso senza il middleware in altri casi d'uso. Con ASP.NET Core 3.0, è consigliabile che tutte le app che richiedono CORS usino il middleware CORS in combinazione con il routing degli endpoint.
UseCors
può essere fornito con un criterio predefinito e [EnableCors]
[DisableCors]
gli attributi possono essere usati per eseguire l'override dei criteri predefiniti, se necessario.
Nell'esempio seguente :
- CORS è abilitato per tutti gli endpoint con i criteri con nome
default
. - La
MyController
classe disabilita CORS con l'attributo[DisableCors]
.
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseCors("default");
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
[DisableCors]
public class MyController : ControllerBase
{
...
}
Autorizzazione
Nelle versioni precedenti di ASP.NET Core il supporto dell'autorizzazione è stato fornito tramite l'attributo [Authorize]
. Il middleware di autorizzazione non era disponibile. In ASP.NET Core 3.0 è necessario il middleware di autorizzazione. È consigliabile posizionare il middleware di autorizzazione core ASP.NET (UseAuthorization
) immediatamente dopo UseAuthentication
. Il middleware di autorizzazione può anche essere configurato con un criterio predefinito, che può essere sottoposto a override.
In ASP.NET Core 3.0 o versione successiva, UseAuthorization
viene chiamato in Startup.Configure
e gli elementi seguenti HomeController
richiedono un utente connesso:
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
public class HomeController : Controller
{
[Authorize]
public IActionResult BuyWidgets()
{
...
}
}
Quando si usa il routing degli endpoint, è consigliabile non configurare AuthorizeFilter e basarsi invece sul middleware di autorizzazione. Se l'app utilizza un AuthorizeFilter
come filtro globale in MVC, è consigliabile effettuare il refactoring del codice per fornire una politica nella chiamata a AddAuthorization
.
è DefaultPolicy
inizialmente configurato per richiedere l'autenticazione, quindi non è necessaria alcuna configurazione aggiuntiva. Nell'esempio seguente gli endpoint MVC vengono contrassegnati come in RequireAuthorization
modo che tutte le richieste debbano essere autorizzate in base a DefaultPolicy
. Tuttavia, HomeController
consente l'accesso senza che l'utente acceda all'app a causa di [AllowAnonymous]
.
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute().RequireAuthorization();
});
}
[AllowAnonymous]
public class HomeController : Controller
{
...
}
Autorizzazione per endpoint specifici
L'autorizzazione può essere configurata anche per classi specifiche di endpoint. Il codice seguente è un esempio di conversione di un'app MVC che ha configurato un'app globale AuthorizeFilter
in un'app con criteri specifici che richiedono l'autorizzazione:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
static readonly string _RequireAuthenticatedUserPolicy =
"RequireAuthenticatedUserPolicy";
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(
options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
// Pre 3.0:
// services.AddMvc(options => options.Filters.Add(new AuthorizeFilter(...));
services.AddControllersWithViews();
services.AddRazorPages();
services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
builder => builder.RequireAuthenticatedUser()));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute()
.RequireAuthorization(_RequireAuthenticatedUserPolicy);
endpoints.MapRazorPages();
});
}
}
È anche possibile personalizzare i criteri. Il DefaultPolicy
è configurato per richiedere l'autenticazione:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(
options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute().RequireAuthorization();
endpoints.MapRazorPages();
});
}
}
[AllowAnonymous]
public class HomeController : Controller
{
In alternativa, tutti gli endpoint possono essere configurati per richiedere l'autorizzazione senza [Authorize]
o RequireAuthorization
configurando un oggetto FallbackPolicy
. L'oggetto FallbackPolicy
è diverso dall'oggetto DefaultPolicy
. L'oggetto DefaultPolicy
viene attivato da [Authorize]
o RequireAuthorization
, mentre l'oggetto FallbackPolicy
viene attivato quando non è impostato alcun altro criterio.
FallbackPolicy
è inizialmente configurato per consentire le richieste senza autorizzazione.
L'esempio seguente è lo stesso dell'esempio precedente DefaultPolicy
, ma usa per FallbackPolicy
richiedere sempre l'autenticazione in tutti gli endpoint tranne quando [AllowAnonymous]
viene specificato:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
}
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
[AllowAnonymous]
public class HomeController : Controller
{
...
}
L'autorizzazione da parte del middleware funziona senza che il framework abbia alcuna conoscenza specifica dell'autorizzazione. Ad esempio, i controlli di integrità non hanno alcuna conoscenza specifica dell'autorizzazione, ma i controlli di integrità possono avere criteri di autorizzazione configurabili applicati dal middleware.
Inoltre, ogni endpoint può personalizzare i requisiti di autorizzazione. Nell'esempio seguente l'autorizzazione UseAuthorization
viene elaborata con DefaultPolicy
, ma l'endpoint del controllo di integrità /healthz
richiede un utente admin
.
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints
.MapHealthChecks("/healthz")
.RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", });
});
}
La protezione viene implementata per alcuni scenari. Il middleware degli endpoint genera un'eccezione se un criterio CORS o di autorizzazione viene ignorato a causa del middleware mancante. Il supporto dell'analizzatore per fornire feedback aggiuntivo sulla configurazione errata è in corso.
Gestori di autorizzazione personalizzati
Se l'app usa gestori personalizzati di autorizzazione, l'instradamento degli endpoint passa un tipo di risorsa diverso ai gestori rispetto a MVC. I gestori che prevedono che la risorsa di contesto del gestore di autorizzazione sia di tipo AuthorizationFilterContext (il tipo di risorsa fornito dai filtri MVC) dovrà essere aggiornata per gestire le risorse di tipo RouteEndpoint (il tipo di risorsa assegnato ai gestori di autorizzazione dal routing dell'endpoint).
MVC usa ancora le AuthorizationFilterContext
risorse, quindi se l'app usa filtri di autorizzazione MVC insieme all'autorizzazione di routing degli endpoint, potrebbe essere necessario gestire entrambi i tipi di risorse.
SignalR
La mappatura degli hub ora avviene all'interno di SignalRUseEndpoints
.
Eseguire il mapping di ogni hub con MapHub
. Come nelle versioni precedenti, ogni hub viene elencato in modo esplicito.
Nell'esempio seguente viene aggiunto il supporto per l'hub ChatHub
SignalR :
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>();
});
}
È disponibile una nuova opzione per controllare i limiti delle dimensioni dei messaggi dai client. Ad esempio: in Startup.ConfigureServices
:
services.AddSignalR(hubOptions =>
{
hubOptions.MaximumReceiveMessageSize = 32768;
});
In ASP.NET Core 2.2, è possibile impostare TransportMaxBufferSize
e che controlla effettivamente le dimensioni massime dei messaggi. In ASP.NET Core 3.0, questa opzione ora limita solo le dimensioni massime prima che si osservi il backpressure.
SignalR assembly nel framework condiviso
Le assembly ASP.NET Core SignalR lato server sono ora installate con il .NET Core SDK. Per altre informazioni, vedere Rimuovere i riferimenti ai pacchetti obsoleti in questo documento.
Controller MVC
Il mapping dei controller ora avviene all'interno di UseEndpoints
.
Aggiungi MapControllers
se l'app usa il routing degli attributi. Poiché il routing include il supporto per molti framework in ASP.NET Core 3.0 o versione successiva, l'aggiunta di controller indirizzati tramite attributi è opzionale.
Sostituire quanto segue:
-
MapRoute
conMapControllerRoute
-
MapAreaRoute
conMapAreaControllerRoute
Poiché il routing include ora il supporto per più di solo MVC, la terminologia è cambiata per rendere questi metodi chiaramente indicare ciò che fanno. Le route convenzionali, MapControllerRoute
/MapAreaControllerRoute
/MapDefaultControllerRoute
ad esempio, vengono applicate nell'ordine in cui vengono aggiunte. Posizionare prima percorsi più specifici (ad esempio itinerari per un'area).
Nell'esempio seguente :
-
MapControllers
aggiunge il supporto per i controller indirizzati con attributi. -
MapAreaControllerRoute
aggiunge una route convenzionale per i controller in un'area. -
MapControllerRoute
aggiunge una route convenzionale per i controller.
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapAreaControllerRoute(
"admin",
"admin",
"Admin/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
"default", "{controller=Home}/{action=Index}/{id?}");
});
}
Rimozione del suffisso asincrono dai nomi delle azioni del controller
In ASP.NET Core 3.0 ASP.NET Core MVC rimuove il Async
suffisso dai nomi delle azioni del controller. Il routing e la generazione dei collegamenti sono interessati da questa nuova impostazione predefinita. Ad esempio:
public class ProductsController : Controller
{
public async Task<IActionResult> ListAsync()
{
var model = await _dbContext.Products.ToListAsync();
return View(model);
}
}
Prima di ASP.NET Core 3.0:
È possibile accedere all'azione precedente nella route Products/ListAsync .
È necessario specificare il suffisso
Async
per la generazione del collegamento. Ad esempio:<a asp-controller="Products" asp-action="ListAsync">List</a>
In ASP.NET Core 3.0:
È possibile accedere all'azione precedente nella route Prodotti/Elenco .
La generazione di collegamenti non richiede la specifica del
Async
suffisso. Ad esempio:<a asp-controller="Products" asp-action="List">List</a>
Questa modifica non influisce sui nomi specificati usando l'attributo [ActionName]
. Il comportamento predefinito può essere disabilitato con il codice seguente in Startup.ConfigureServices
:
services.AddMvc(options =>
options.SuppressAsyncSuffixInActionNames = false);
Modifiche alla generazione di collegamenti
Esistono alcune differenze nella generazione dei collegamenti (ad esempio usando Url.Link
e API simili). tra cui:
- Per impostazione predefinita, quando si usa il routing degli endpoint, la formattazione dei parametri di route negli URI generati non viene necessariamente mantenuta. Questo comportamento può essere controllato con l'interfaccia
IOutboundParameterTransformer
. - La generazione di un URI per una route non valida (un controller o un'azione o una pagina che non esiste) produrrà una stringa vuota nel routing dell'endpoint anziché produrre un URI non valido.
- I valori di ambiente (parametri di route dal contesto corrente) non vengono usati automaticamente nella generazione di collegamenti con il routing dell'endpoint. In precedenza, quando si genera un collegamento a un'altra azione (o pagina), i valori di route non specificati verrebbero dedotti dai valori di ambiente delle route correnti . Quando si usa il routing degli endpoint, tutti i parametri di route devono essere specificati in modo esplicito durante la generazione del collegamento.
Razor Pagine
Il mapping delle pagine Razor si svolge ora all'interno di UseEndpoints
.
Aggiungi MapRazorPages
se l'app usa Razor Pages. Poiché il routing degli endpoint include il supporto per molti framework, l'aggiunta di Razor Pagine richiede ora un'adesione.
Nel seguente metodo Startup.Configure
, MapRazorPages
aggiunge supporto per Razor Pagine:
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Usare MVC senza routing degli endpoint
L'uso di MVC tramite UseMvc
o UseMvcWithDefaultRoute
in ASP.NET Core 3.0 richiede un'adesione esplicita all'interno di Startup.ConfigureServices
. Questa operazione è necessaria perché MVC deve sapere se può basarsi sull'autorizzazione e sul middleware CORS durante l'inizializzazione. Viene fornito un analizzatore che avvisa se l'app tenta di usare una configurazione non supportata.
Se l'app richiede il supporto legacy IRouter
, disattiva EnableEndpointRouting
utilizzando uno degli approcci seguenti in Startup.ConfigureServices
:
services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddControllers(options => options.EnableEndpointRouting = false);
services.AddControllersWithViews(options => options.EnableEndpointRouting = false);
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);
Controlli di integrità
I controlli di integrità possono essere usati come router-ware con routing degli endpoint.
Aggiungere MapHealthChecks
per usare i controlli di integrità con il routing degli endpoint. Il MapHealthChecks
metodo accetta argomenti simili a UseHealthChecks
. Il vantaggio dell'uso di MapHealthChecks
rispetto a UseHealthChecks
è la possibilità di applicare l'autorizzazione e di avere un maggiore controllo granulare sulla politica di corrispondenza.
Nel seguente esempio, MapHealthChecks
viene chiamato come endpoint di controllo dello stato di salute in /healthz
:
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/healthz", new HealthCheckOptions() { });
});
}
HostBuilder sostituisce WebHostBuilder
I modelli di ASP.NET Core 3.0 usano l'host generico. Le versioni precedenti usavano Web Host. Il codice seguente illustra la classe generata Program
dal modello ASP.NET Core 3.0:
// requires using Microsoft.AspNetCore.Hosting;
// requires using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Il codice seguente illustra la classe generata dal Program
modello ASP.NET Core 2.2:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
IWebHostBuilder rimane nella versione 3.0 ed è il tipo dell'oggetto webBuilder
visualizzato nell'esempio di codice precedente.
WebHostBuilder verrà deprecato in una versione futura e sostituito da HostBuilder
.
La modifica più significativa da WebHostBuilder
a HostBuilder
è nell'iniezione di dipendenze (DI). Quando si usa HostBuilder
, è possibile inserire solo il codice seguente nel Startup
costruttore di :
Vincoli di inserimento delle dipendenze HostBuilder
:
- Abilitare il container DI per essere costruito una sola volta.
- Evita problemi legati alla vita degli oggetti risultanti, come la gestione di più istanze di singleton.
Per altre informazioni, vedere Evitare l'inserimento del servizio di avvio in ASP.NET Core 3.
Il metodo AddAuthorization è stato spostato in un assembly diverso.
I metodi ASP.NET Core 2.2 e versioni precedenti AddAuthorization
in Microsoft.AspNetCore.Authorization.dll:
- Sono stati rinominati
AddAuthorizationCore
. - Sono stati spostati in Microsoft.AspNetCore.Authorization.Policy.dll.
Le app che usano sia Microsoft.AspNetCore.Authorization.dllche Microsoft.AspNetCore.Authorization.Policy.dll non sono interessate.
Le app che non usano Microsoft.AspNetCore.Authorization.Policy.dll devono eseguire una delle operazioni seguenti:
- Aggiungere un riferimento a Microsoft.AspNetCore.Authorization.Policy.dll. Questo approccio funziona per la maggior parte delle app ed è tutto ciò che è necessario.
- Passare a utilizzare
AddAuthorizationCore
Per ulteriori informazioni, vedere Modifica sostanziale in cui l'overload risiede in un assembly diverso #386.
Identity Interfaccia Utente
Identity Aggiornamenti dell'interfaccia utente per ASP.NET Core 3.0:
- Aggiungere un riferimento al pacchetto a Microsoft.AspNetCore.UI.
- Le app che non usano Razor Pages devono chiamare
MapRazorPages
. Vedere Razor Pagine in questo documento. - Bootstrap 4 è il framework predefinito dell'interfaccia utente. Impostare una
IdentityUIFrameworkVersion
proprietà del progetto per modificare il valore predefinito. Per altre informazioni, vedere questo annuncio di GitHub.
SignalR
Il SignalR client JavaScript è passato da @aspnet/signalr
a @microsoft/signalr
. Per reagire a questa modifica, cambiare i riferimenti nei file package.json
, nelle istruzioni require
e nelle istruzioni ECMAScript import
.
System.Text.Json è il protocollo predefinito
System.Text.Json
è ora il protocollo hub predefinito usato sia dal client che dal server.
In Startup.ConfigureServices
chiamare AddJsonProtocol
per impostare le opzioni del serializzatore.
Server:
services.AddSignalR(...)
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.WriteIndented = false;
})
Client:
new HubConnectionBuilder()
.WithUrl("/chathub")
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.WriteIndented = false;
})
.Build();
Passare a Newtonsoft.Json
Se si usano funzionalità di Newtonsoft.Json non supportate in System.Text.Json, è possibile tornare a Newtonsoft.Json
. Vedere SignalR ASP.NET Core 3.0 in precedenza in questo articolo.
Cache distribuite Redis
Il pacchetto Microsoft.Extensions.Caching.Redis non è disponibile per le app ASP.NET Core 3.0 o versioni successive. Sostituire il riferimento al pacchetto con Microsoft.Extensions.Caching.StackExchangeRedis. Per altre informazioni, vedere Memorizzazione nella cache distribuita in ASP.NET Core.
Acconsentire esplicitamente alla compilazione in fase di esecuzione
Prima di ASP.NET Core 3.0, la compilazione in fase di esecuzione delle visualizzazioni era una funzionalità implicita del framework. La compilazione in fase di esecuzione integra la compilazione al momento della build delle viste. Consente al framework di compilare Razor visualizzazioni e pagine (.cshtml
file) quando i file vengono modificati, senza dover ricompilare l'intera app. Questa funzionalità supporta lo scenario di apportare una modifica rapida nell'IDE e aggiornare il browser per visualizzare le modifiche.
In ASP.NET Core 3.0 la compilazione di runtime è uno scenario di consenso esplicito. La compilazione in fase di build è l'unico meccanismo per la compilazione della vista abilitato per impostazione predefinita. Il runtime si basa su Visual Studio o dotnet-watch in Visual Studio Code per ricompilare il progetto quando rileva le modifiche apportate ai .cshtml
file. In Visual Studio le modifiche apportate ai .cs
file , .cshtml
o .razor
del progetto in esecuzione (CTRL+F5), ma non al debug (F5), attivano la ricompilazione del progetto.
Per abilitare la compilazione in fase di esecuzione nel progetto ASP.NET Core 3.0:
Installare il pacchetto NuGet Microsoft.AspNetCore.Mvc.RuntimeCompilation.
Aggiornare
Startup.ConfigureServices
per chiamareAddRazorRuntimeCompilation
:Per ASP.NET Core MVC, usare il codice seguente:
services.AddControllersWithViews() .AddRazorRuntimeCompilation(...);
Per ASP.NET Core Pages Razor, usare il codice seguente:
services.AddRazorPages() .AddRazorRuntimeCompilation(...);
L'esempio in https://github.com/aspnet/samples/tree/main/samples/aspnetcore/mvc/runtimecompilation mostra un esempio di abilitazione condizionale della compilazione in fase di esecuzione negli ambienti di sviluppo.
Per altre informazioni sulla Razor compilazione dei file, vedere Razor Compilazione di file in ASP.NET Core.
Eseguire la migrazione di librerie tramite multitargeting
Le librerie spesso devono supportare più versioni di ASP.NET Core. La maggior parte delle librerie compilate rispetto alle versioni precedenti di ASP.NET Core deve continuare a funzionare senza problemi. Le condizioni seguenti richiedono la compilazione incrociata dell'app:
- La libreria si basa su una funzionalità che presenta una modifica di rilievo binaria.
- La libreria vuole sfruttare le nuove funzionalità di ASP.NET Core 3.0.
Ad esempio:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
</ItemGroup>
</Project>
Usare #ifdefs
per abilitare ASP.NET API specifiche di Core 3.0:
var webRootFileProvider =
#if NETCOREAPP3_0
GetRequiredService<IWebHostEnvironment>().WebRootFileProvider;
#elif NETSTANDARD2_0
GetRequiredService<IHostingEnvironment>().WebRootFileProvider;
#else
#error unknown target framework
#endif
Per altre informazioni sull'uso delle API di base ASP.NET in una libreria di classi, vedere Usare le API di base ASP.NET in una libreria di classi.
Modifiche varie
Il sistema di convalida in .NET Core 3.0 e versioni successive considera parametri non nullable o proprietà associate come se avessero un [Required]
attributo. Per altre informazioni, vedere attributo [Obbligatorio].
Pubblicazione
Eliminare le cartelle bin e obj nella directory del progetto.
Server di Test
Per le app che usano TestServer direttamente con il Host Generico, crea il TestServer
su un IWebHostBuilder in ConfigureWebHost.
[Fact]
public async Task GenericCreateAndStartHost_GetTestServer()
{
using var host = await new HostBuilder()
.ConfigureWebHost(webBuilder =>
{
webBuilder
.UseTestServer()
.Configure(app => { });
})
.StartAsync();
var response = await host.GetTestServer().CreateClient().GetAsync("/");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
Modifiche che causano un'interruzione dell'API
Rivedere le modifiche che causano un'interruzione:
- Elenco completo delle modifiche di rilievo nella versione ASP.NET Core 3.0
- Modifiche di rottura dell'API in Antiforgery, CORS, Diagnostica, MVC e Routing. Questo elenco include modifiche di rilievo per le opzioni di compatibilità.
- Per un riepilogo delle modifiche di rilievo da 2.2 a 3.0 in .NET Core, ASP.NET Core ed Entity Framework Core, vedere Modifiche di rilievo per la migrazione dalla versione 2.2 alla 3.0.
Routing degli endpoint con parametro catch-all
Avviso
Un parametro catch-all può corrispondere erroneamente alle route a causa di un bug nel routing. Le app interessate da questo bug presentano le caratteristiche seguenti:
- Un percorso onnicomprensivo, ad esempio
{**slug}"
- La route catch-all non riesce ad abbinare le richieste che dovrebbe abbinare.
- La rimozione di altre rotte permette alla rotta catch-all di iniziare a funzionare.
Vedere i bug di GitHub 18677 e 16579 per casi di esempio che sono stati colpiti da questo bug.
Una correzione di consenso esplicito per questo bug è contenuta in .NET Core 3.1.301 SDK e versioni successive. Il codice seguente imposta un commutatore interno che corregge questo bug:
public static void Main(string[] args)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior",
true);
CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.
.NET Core 3.0 nel servizio app Azure
L'implementazione di .NET Core per Azure App Service è stata completata. .NET Core 3.0 è disponibile in tutti i data center del servizio app Azure.
Modulo ASP.NET Core (ANCM)
Se la ASP.NET Core Module (ANCM) non è un componente selezionato quando Visual Studio è stato installato o se è stata installata una versione precedente di ANCM nel sistema, scaricare l'ultimo programma di installazione del bundle di hosting .NET Core (download diretto) ed eseguire il programma di installazione. Per altre informazioni, vedere Bundle di hosting.