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

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. Impostare 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:

  • <PropertyGroup>In :

    • Aggiornamenti tfm anetcoreapp3.0
    • Rimuove l'elemento <AspNetCoreHostingModel> . Per altre informazioni, vedere Modello di hosting in-process in questo documento.
  • <ItemGroup>In :

    • Microsoft.AspNetCore.App viene rimosso. Per altre informazioni, vedere Informazioni di riferimento sul framework in questo documento.
    • Microsoft.AspNetCore.Razor.Design viene rimosso e nell'elenco seguente di pacchetti 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.CookiePolitica
  • 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.RazorPagine
  • 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. Nucleo
  • 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. Nucleo
  • Microsoft.AspNetCore.StaticFiles
  • Microsoft.AspNetCore.WebSockets
  • Microsoft.AspNetCore.WebUtilities
  • Microsoft.Net.Http.Headers

Rivedere le modifiche che causano un'interruzione

Rivedere le modifiche che causano un'interruzione

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 con estensione 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 al Microsoft.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 destinati Microsoft.NET.Sdk o Microsoft.NET.Sdk.Razor SDK devono aggiungere un oggetto esplicito FrameworkReference a Microsoft.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 ON seguente JSmostra 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:

shared framework assemblies comparison

Per continuare a usare le funzionalità fornite dagli assembly rimossi, fare riferimento alle versioni 3.0 dei pacchetti corrispondenti:

Modifiche all'avvio

L'immagine seguente mostra le righe eliminate e modificate in un'app Web ASP.NET Core 2.2 Razor Pages:

the deleted and changed lines in an ASP.NET Core 2.2 Razor Web app

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:

the added and changed lines in an ASP.NET Core 3.0 Razor Web app

Nell'immagine precedente viene visualizzato il codice aggiunto in verde. Per informazioni sulle modifiche seguenti:

  • services.AddMvc per services.AddRazorPages, vedere Registrazione del servizio MVC in questo documento.
  • CompatibilityVersion, vedere Versione di compatibilità per ASP.NET Core MVC.
  • IHostingEnvironment per IWebHostEnvironment, vedere questo annuncio di GitHub.
  • app.UseAuthorization è stato aggiunto ai modelli per visualizzare il middleware di autorizzazione dell'ordine deve essere aggiunto. Se l'app non usa l'autorizzazione, è possibile rimuovere in modo sicuro la chiamata a app.UseAuthorization.
  • app.UseEndpoints, vedere Razor Pages or Migrate Startup.Configure in questo documento.

Supporto dell'analizzatore

Progetti destinati Microsoft.NET.Sdk.Web agli analizzatori di riferimento implicito forniti in precedenza come parte del pacchetto Microsoft.AspNetCore.Mvc.Analyzers . Non sono necessari riferimenti aggiuntivi per abilitarli.

Se l'app usa analizzatori API forniti in precedenza usando il pacchetto Microsoft.AspNetCore.Mvc.Api.Analyzers , modificare il file di progetto per fare riferimento agli analizzatori forniti come parte di .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 della 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 sono 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é , chiamare UseKestrel sul generatore di ConfigureWebHostDefaultshost 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();
}

Connessione ion Middleware sostituisce gli adapter Connessione ion

gli adapter Connessione ion (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) sono stati rimossi da Kestrel. Sostituire gli adattatori Connessione ion con middleware di Connessione ion. Connessione middleware è simile al middleware HTTP nella pipeline ASP.NET Core, ma per le connessioni di livello inferiore. Registrazione https e connessione:

  • Sono stati spostati dagli adapter di Connessione al middleware di Connessione ion.
  • Questi metodi di estensione funzionano come nelle versioni precedenti di ASP.NET Core.

Per altre informazioni, vedere l'esempio TlsFilter Connessione ionHandler nella sezione ListenOptions.Protocols dell'articoloKestrel.

Astrazioni di trasporto spostate e rese pubbliche

Il Kestrel livello di trasporto è stato esposto come interfaccia pubblica in Connections.Abstractions. Come parte 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:

Kestrel Intestazioni del trailer della 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 il corpo della richiesta viene letto 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 alla fine.

Per la versione 3.0 sono disponibili i metodi seguenti RequestTrailerExtensions :

  • GetDeclaredTrailers: ottiene l'intestazione della richiesta Trailer che elenca i trailer previsti dopo il corpo.
  • SupportsTrailers: indica se la richiesta supporta la ricezione di intestazioni trailer.
  • CheckTrailersAvailable: controlla se la richiesta supporta trailer e se sono disponibili per la lettura. Questo controllo non presuppone che ci siano trailer da leggere. Potrebbe non esserci trailer da leggere anche se true viene restituito da questo metodo.
  • GetTrailer: ottiene l'intestazione finale richiesta dalla risposta. Controllare SupportsTrailers prima di chiamare GetTrailero NotSupportedException se la richiesta non supporta le intestazioni finali.

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.Writee Stream.Flush. Queste API sono un'origine di fame di thread che causa arresti anomali dell'app. La versione 3.0 AllowSynchronousIO è disabilitata 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 si verificano problemi con TextWriter le implementazioni o altri flussi che chiamano API sincrone in Dispose, chiamare invece 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 usando questi formattatori.

System.Text.Json supporta la serializzazione asincrona e di conseguenza il formattatore basato non esegue il System.Text.Json buffer. 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 la generazione di un'eccezione di runtime se AllowSynchronousIO non è configurato.

Microsoft.AspNetCore.Server.Kestrel. Assembly HTTPS rimosso

In ASP.NET Core 2.1, il contenuto di Microsoft.AspNetCore.Server.Kestrel. Https.dll è stato spostato in Microsoft.AspNetCore.Server.Kestrel. Core.dll. Si tratta di un aggiornamento non di rilievo che usa TypeForwardedTo attributi. Per la versione 3.0, microsoft.AspNetCore.Server.vuotaKestrel. L'assembly Https.dll e il pacchetto NuGet sono stati rimossi.

Librerie che fanno riferimento a Microsoft.AspNetCore.Server.Kestrel. Https deve aggiornare ASP.NET dipendenze core alla versione 2.1 o successiva.

Le app e le librerie destinate ASP.NET Core 2.1 o versione successiva devono rimuovere i riferimenti diretti a Microsoft.AspNetCore.Server.Kestrel Pacchetto 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 ON predefinito JSper ASP.NET Core è ora System.Text.Json, che è una novità di .NET Core 3.0. Prendere in considerazione l'uso System.Text.Json quando possibile. Si tratta di prestazioni elevate e non richiede una dipendenza di 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 Microsoft.AspNetCore.SignalR. Pacchetto NuGet Protocols.NewtonsoftJson.

  • Nel client concatenare una AddNewtonsoftJsonProtocol chiamata al metodo all'istanza HubConnectionBuilder :

    new HubConnectionBuilder()
        .WithUrl("/chathub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  • Nel server concatenare una AddNewtonsoftJsonProtocol chiamata al metodo alla chiamata al AddSignalR metodo in Startup.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 chiamare AddNewtonsoftJson.

    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 a AddNewtonsoftJson:

    services.AddMvc()
        .AddNewtonsoftJson(options =>
               options.SerializerSettings.ContractResolver =
                  new CamelCasePropertyNamesContractResolver());
    

    Nota: se il AddNewtonsoftJson metodo non è disponibile, assicurarsi di aver installato il Microsoft.AspNetCore.Mvc.NewtonsoftJson pacchetto. Un errore comune consiste nell'installare il pacchetto Newtonsoft.Json anziché il Microsoft.AspNetCore.Mvc.NewtonsoftJson pacchetto.

Per altre informazioni, vedere Aggiungere il supporto del formato ON basato su JSNewtonsoft.Json.

Registrazione del servizio MVC

ASP.NET Core 3.0 aggiunge nuove opzioni per la registrazione di scenari MVC all'interno Startup.ConfigureServicesdi .

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, eseguire la migrazione dell'app al routing degli endpoint, 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 da Route, 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 la route con un nome di route.
    • 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, posizionare UseStaticFilesprimaUseRouting.

  • Se l'app usa funzionalità di autenticazione/autorizzazione, AuthorizePage ad esempio o [Authorize], inserire la chiamata a UseAuthentication e UseAuthorization: after, UseRouting e UseCors, ma prima UseEndpointsdi :

    public void Configure(IApplicationBuilder app)
    {
      ...
    
      app.UseStaticFiles();
    
      app.UseRouting();
      app.UseCors();
    
      app.UseAuthentication();
      app.UseAuthorization();
    
      app.UseEndpoints(endpoints => {
         endpoints.MapControllers();
      });
    
  • Sostituire UseMvc o UseSignalR con UseEndpoints.

  • Se l'app usa scenari CORS , ad esempio [EnableCors], posizionare la chiamata a UseCors prima di qualsiasi altro middleware che usa CORS ( ad esempio, posizionare UseCors prima UseAuthenticationdi , UseAuthorizatione UseEndpoints).

  • Sostituire IHostingEnvironment con IWebHostEnvironment e aggiungere un'istruzione using per lo spazio dei Microsoft.AspNetCore.Hosting nomi .

  • 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, UseAuthorizatione UseCors devono essere visualizzate tra le chiamate a UseRouting e UseEndpoints per essere efficaci.

Controlli di integrità

I controlli di integrità usano il routing degli endpoint con l'host generico. In Startup.Configurechiamare 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.
  • Richiedere CORS.

Per altre informazioni, vedere Controlli di integrità in ASP.NET Core.

Indicazioni sul middleware per la sicurezza

Il supporto per l'autorizzazione e CORS è unificato rispetto 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.

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 default criteri denominati.
  • 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.Configuree 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 configurare AuthorizeFilter e basarsi invece sul middleware di autorizzazione. Se l'app usa come AuthorizeFilter filtro globale in MVC, è consigliabile effettuare il refactoring del codice per fornire un criterio 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, consente l'accesso HomeController senza che l'utente accinga 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. è 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 FallbackPolicyDefaultPolicyè diverso da . 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 , DefaultPolicyma l'endpoint del /healthz controllo integrità richiede un admin utente:

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 di autorizzazione personalizzati, il routing degli endpoint passa un tipo di risorsa diverso ai gestori di 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

Il mapping degli hub ora avviene all'interno UseEndpointsdi SignalR .

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 ChatHubSignalR :

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 controlla solo le dimensioni massime prima che venga osservata la backpressure.

SignalR assembly nel framework condiviso

ASP.NET assembly lato server Core SignalR sono ora installati con .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 UseEndpointsdi .

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 è esplicita.

Sostituire quanto segue:

  • MapRoute con MapControllerRoute
  • MapAreaRoute con MapAreaControllerRoute

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//MapAreaControllerRouteMapDefaultControllerRoute 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 .

  • Generazione del collegamento necessaria per specificare il Async suffisso. 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);

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, l'uso di maiuscole e minuscole dei parametri di route negli URI generati non viene necessariamente mantenuto. 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 Pages

Le pagine di mapping Razor vengono ora eseguite all'interno UseEndpointsdi .

Aggiungi MapRazorPages se l'app usa Razor Pages. Poiché il routing degli endpoint include il supporto per molti framework, l'aggiunta Razor di Pagine è ora esplicita.

Nel metodo seguente Startup.Configure viene aggiunto il supporto per RazorMapRazorPages Pages:

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 consenso esplicito all'interno Startup.ConfigureServicesdi . 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 , disabilitare EnableEndpointRouting l'uso di 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 MapHealthChecks di oltre UseHealthChecks è la possibilità di applicare l'autorizzazione e di avere un maggiore controllo granulare sui criteri di corrispondenza.

Nell'esempio MapHealthChecks seguente viene chiamato per un endpoint di controllo integrità 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. Versioni precedenti usano l'host Web. 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 a è nell'inserimento delle dipendenze (DI).The most significant change from WebHostBuilder to is in dependency injection (DI)HostBuilder. Quando si usa HostBuilder, è possibile inserire solo il codice seguente nel Startupcostruttore di :

Vincoli di inserimento delle dipendenze HostBuilder :

  • Abilitare il contenitore di inserimento delle dipendenze per la compilazione una sola volta.
  • Evita i problemi di durata dell'oggetto risultanti, ad esempio la risoluzione di più istanze di singleton.

Per altre informazioni, vedere Evitare l'inserimento del servizio di avvio in ASP.NET Core 3.

AddAuthorization 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 all'uso AddAuthorizationCore

Per altre informazioni, vedere Interruzione dell'overload in AddAuthorization(o =>) in un assembly diverso #386.

Identity UI

Identity Aggiornamenti dell'interfaccia utente per ASP.NET Core 3.0:

  • Aggiungere un riferimento al pacchetto a Microsoft.AspNetCore.Identity. Interfaccia utente.
  • 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, modificare i riferimenti in package.json file, require istruzioni ed 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.ConfigureServiceschiamare 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 Usare Newtonsoft.Json in un progetto ASP.NET Core 3.0 SignalR 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 in fase di compilazione delle visualizzazioni. 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 compilazione è l'unico meccanismo per la compilazione della visualizzazione abilitata 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 .csfile , .cshtmlo .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:

  1. Installare Microsoft.AspNetCore.Mvc.Razor. Pacchetto NuGet RuntimeCompilation.

  2. Aggiornare Startup.ConfigureServices per chiamare AddRazorRuntimeCompilation:

    Per ASP.NET Core MVC, usare il codice seguente:

    services.AddControllersWithViews()
        .AddRazorRuntimeCompilation(...);
    

    Per ASP.NET Pagine principali 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].

Pagina

Eliminare le cartelle bin e obj nella directory del progetto.

TestServer

Per le app che usano TestServer direttamente con l'host generico, creare in ConfigureWebHostTestServerIWebHostBuilder in :

[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:

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 itinerario catch-all, ad esempio {**slug}"
  • La route catch-all non riesce a trovare una corrispondenza con le richieste che deve corrispondere.
  • La rimozione di altre route rende la route catch-all iniziare a funzionare.

Vedere Bug di GitHub 18677 e 16579 per casi di esempio che hanno raggiunto 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 app Azure servizio è 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.