Novità di ASP.NET Core 6.0
Questo articolo illustra le modifiche più significative in ASP.NET Core 6.0 con collegamenti alla documentazione pertinente.
ASP.NET Core MVC e Razor miglioramenti
API minime
Le API minime sono progettata per creare API HTTP con dipendenze minime. Sono ideali per microservizi e app che vogliono includere solo i file, le funzionalità e le dipendenze minimi in ASP.NET Core. Per altre informazioni, vedi:
- Esercitazione: Creare un'API minima con ASP.NET Core
- Differenze tra API minime e API con controller
- Informazioni di riferimento rapido sulle API minime
- Esempi di codice migrati al nuovo modello di hosting minimo nella versione 6.0
SignalR
Tag di attività a esecuzione prolungata per SignalR le connessioni
SignalR usa il nuovo Microsoft.AspNetCore.Http.Features.IHttpActivityFeature.Activity oggetto per aggiungere un http.long_running
tag all'attività della richiesta. IHttpActivityFeature.Activity
viene usato dai servizi APM come Application Insights di Monitoraggio di Azure per filtrare SignalR le richieste dalla creazione di avvisi di richiesta a esecuzione prolungata.
Miglioramenti delle prestazioni SignalR
- Allocare HubCallerClients una sola volta per ogni connessione anziché ogni chiamata al metodo hub.
- Evitare l'allocazione di chiusura in SignalR
DefaultHubDispatcher.Invoke
. Lo stato viene passato a una funzione statica locale tramite parametri per evitare un'allocazione di chiusura. Per altre informazioni, vedere questa richiesta pull di GitHub. - Allocare un singolo StreamItemMessage flusso invece di ogni elemento di flusso nel flusso da server a client. Per altre informazioni, vedere questa richiesta pull di GitHub.
Razor compilatore
Razor compilatore aggiornato per l'uso dei generatori di origine
Il Razor compilatore è ora basato su generatori di origine C#. I generatori di origine vengono eseguiti durante la compilazione e controllano cosa viene compilato per produrre file aggiuntivi compilati insieme al rest del progetto. L'uso dei generatori di origine semplifica il Razor compilatore e accelera notevolmente i tempi di compilazione.
Razor il compilatore non produce più un assembly di viste separato
Il Razor compilatore ha usato in precedenza un processo di compilazione in due passaggi che ha generato un assembly Views separato che conteneva le visualizzazioni e le pagine generate (.cshtml
file) definite nell'app. I tipi generati erano pubblici e nello spazio dei AspNetCore
nomi .
Il compilatore aggiornato Razor compila le visualizzazioni e i tipi di pagine nell'assembly di progetto principale. Questi tipi vengono ora generati per impostazione predefinita come sealed interno nello spazio dei AspNetCoreGeneratedDocument
nomi. Questa modifica migliora le prestazioni di compilazione, consente la distribuzione di singoli file e consente a questi tipi di partecipare a Ricaricamento rapido.
Per altre informazioni su questa modifica, vedere il problema relativo all'annuncio in GitHub.
miglioramenti delle prestazioni e delle API principali ASP.NET
Sono state apportate molte modifiche per ridurre le allocazioni e migliorare le prestazioni nello stack:
- App non allocabile . Usare il metodo di estensione. Il nuovo overload di
app.Use
richiede il passaggio del contesto anext
cui vengono salvate due allocazioni interne per richiesta necessarie quando si usa l'altro overload. - Riduzione delle allocazioni di memoria durante l'accesso a HttpRequest.Cookies. Per altre informazioni, vedere questo problema in GitHub.
- Usare LoggerMessage.Define per le finestre solo HTTP.sys server Web. Le chiamate ai ILogger metodi di estensione sono state sostituite con chiamate a
LoggerMessage.Define
. - Ridurre il sovraccarico per connessione in SocketConnection di circa il 30%. Per altre informazioni, vedere questa richiesta pull di GitHub.
- Ridurre le allocazioni rimuovendo i delegati di registrazione nei tipi generici. Per altre informazioni, vedere questa richiesta pull di GitHub.
- Accesso GET più rapido (circa il 50%) alle funzionalità di uso comune, ad IHttpRequestFeatureesempio , IHttpResponseFeatureIHttpResponseBodyFeature, IRouteValuesFeature, e IEndpointFeature. Per altre informazioni, vedere questa richiesta pull di GitHub.
- Usare stringhe a istanza singola per i nomi di intestazione noti, anche se non si trovano nel blocco di intestazione conservato. L'uso di una singola stringa di istanza consente di evitare più duplicati della stessa stringa in connessioni di lunga durata, ad esempio in Microsoft.AspNetCore.WebSockets. Per altre informazioni, vedere questo problema in GitHub.
- Riutilizzare HttpProtocol CancellationTokenSource in Kestrel. Usare il nuovo metodo CancellationTokenSource.TryReset su
CancellationTokenSource
per riutilizzare i token se non sono stati annullati. Per altre informazioni, vedere questo problema di GitHub e questo video. - Implementare e usare adaptiveCapacityDictionary in Microsoft.AspNetCore.Http RequestCookieCollection per un accesso più efficiente ai dizionari. Per altre informazioni, vedere questa richiesta pull di GitHub.
Footprint di memoria ridotto per le connessioni TLS inattive
Per le connessioni TLS a esecuzione prolungata in cui i dati vengono inviati solo occasionalmente in avanti e indietro, è stato notevolmente ridotto il footprint di memoria delle app ASP.NET Core in .NET 6. Ciò dovrebbe contribuire a migliorare la scalabilità degli scenari, ad esempio i server WebSocket. Ciò è stato possibile a causa di numerosi miglioramenti in System.IO.Pipelines, SslStreame Kestrel. Le sezioni seguenti illustrano in dettaglio alcuni dei miglioramenti apportati al footprint di memoria ridotto:
Ridurre le dimensioni di System.IO.Pipelines.Pipe
Per ogni connessione stabilita, due pipe vengono allocate in Kestrel:
- Livello di trasporto per l'app per la richiesta.
- Livello applicazione per il trasporto per la risposta.
Riducendo le dimensioni di da 368 byte a 264 byte (circa una riduzione del System.IO.Pipelines.Pipe 28,2%), vengono salvati 208 byte per connessione (104 byte per pipe).
Pool SocketSender
SocketSender
gli oggetti (che sottoclasse SocketAsyncEventArgs) sono circa 350 byte in fase di esecuzione. Anziché allocare un nuovo SocketSender
oggetto per ogni connessione, è possibile eseguire il pooling. SocketSender
gli oggetti possono essere inseriti in pool perché gli invii sono in genere molto veloci. Il pooling riduce il sovraccarico per connessione. Anziché allocare 350 byte per connessione, vengono allocati solo 350 byte per IOQueue
ogni connessione. L'allocazione viene eseguita per coda per evitare conflitti. Il server WebSocket con 5000 connessioni inattive è passato dall'allocazione di ~1,75 MB (350 byte * 5000) all'allocazione di ~2,8 kb (350 byte * 8) per SocketSender
gli oggetti.
Letture in byte zero con SslStream
Le letture senza buffer sono una tecnica usata in ASP.NET Core per evitare di noleggiare memoria dal pool di memoria se non sono disponibili dati nel socket. Prima di questa modifica, il server WebSocket con 5000 connessioni inattive richiedeva circa 200 MB senza TLS rispetto a ~800 MB con TLS. Alcune di queste allocazioni (4k per connessione) non devono Kestrel essere bloccate in un ArrayPool<T> buffer durante l'attesa del completamento delle letture SslStream . Dato che queste connessioni sono inattive, nessuna delle letture è stata completata e ha restituito i buffer a ArrayPool
, forzando l'allocazione ArrayPool
di più memoria. Le allocazioni rimanenti erano in SslStream
sé: buffer 4k per handshake TLS e buffer di 32k per le letture normali. In .NET 6, quando l'utente esegue una lettura SslStream
a zero byte e non dispone di dati disponibili, SslStream
esegue internamente una lettura a zero byte nel flusso di cui è stato eseguito il wrapping sottostante. Nel caso migliore (connessione inattiva), queste modifiche comportano un risparmio di 40 KB per connessione, consentendo al consumer (Kestrel) di ricevere una notifica quando i dati sono disponibili senza tenere premuti alcun buffer inutilizzato.
Letture a byte zero con PipeReader
Con le letture senza buffer supportate in SslStream
, è stata aggiunta un'opzione per eseguire letture di byte zero in StreamPipeReader
, il tipo interno che si adatta a Stream
in un oggetto PipeReader
. In Kestrel, unStreamPipeReader
oggetto viene usato per adattare l'oggetto sottostante SslStream
in un oggetto PipeReader
. Pertanto, è stato necessario esporre la semantica di lettura zero byte in PipeReader
.
È ora possibile creare un PipeReader
oggetto che supporta zero byte letti su qualsiasi elemento sottostante Stream
che supporta la semantica di lettura zero byte (ad esempio SslStream
, , e NetworkStreamcosì via) usando l'API seguente:
var reader = PipeReader.Create(stream, new StreamPipeReaderOptions(useZeroByteReads: true));
Rimuovere le lastre dall'oggetto SlabMemoryPool
Per ridurre la frammentazione dell'heap, Kestrel è stata usata una tecnica in cui sono stati allocati lastre di memoria di 128 KB come parte del relativo pool di memoria. Le lastre sono state poi ulteriormente suddivise in blocchi da 4 KB usati Kestrel internamente. Le lastre devono essere superiori a 85 KB per forzare l'allocazione nell'heap di oggetti di grandi dimensioni per tentare e impedire al GC di rilocare questa matrice. Tuttavia, con l'introduzione della nuova generazione GC, l'heap dell'oggetto aggiunto (POH), non ha più senso allocare blocchi sulla lastra. Kestrel ora alloca direttamente i blocchi nel POH, riducendo la complessità della gestione del pool di memoria. Questa modifica dovrebbe semplificare l'esecuzione di miglioramenti futuri, ad esempio semplificando la compattazione del pool di memoria usato da Kestrel.
IAsyncDisposable supportato
IAsyncDisposable è ora disponibile per controller, Razor pagine e componenti di visualizzazione. Le versioni asincrone sono state aggiunte alle interfacce pertinenti nelle factory e negli attivatori:
- I nuovi metodi offrono un'implementazione di interfaccia predefinita che delega alla versione sincrona e chiama Dispose.
- Le implementazioni sostituiscono l'implementazione predefinita e gestiscono l'eliminazione
IAsyncDisposable
delle implementazioni. - Le implementazioni prediligono
IAsyncDisposable
IDisposable
quando vengono implementate entrambe le interfacce. - Gli extender devono eseguire l'override dei nuovi metodi inclusi per supportare
IAsyncDisposable
le istanze.
IAsyncDisposable
è utile quando si lavora con:
- Enumeratori asincroni, ad esempio, in flussi asincroni.
- Risorse non gestite con operazioni di I/O a elevato utilizzo di risorse da rilasciare.
Quando si implementa questa interfaccia, usare il DisposeAsync
metodo per rilasciare le risorse.
Si consideri un controller che crea e usa un oggetto Utf8JsonWriter. Utf8JsonWriter
è una IAsyncDisposable
risorsa:
public class HomeController : Controller, IAsyncDisposable
{
private Utf8JsonWriter? _jsonWriter;
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
_jsonWriter = new Utf8JsonWriter(new MemoryStream());
}
IAsyncDisposable
deve implementare DisposeAsync
:
public async ValueTask DisposeAsync()
{
if (_jsonWriter is not null)
{
await _jsonWriter.DisposeAsync();
}
_jsonWriter = null;
}
Porta Vcpkg per SignalR il client C++
Vcpkg è una gestione pacchetti da riga di comando multipiattaforma per le librerie C e C++. Di recente è stata aggiunta una porta per vcpkg
aggiungere CMake
il supporto nativo per il SignalR client C++. vcpkg
funziona anche con MSBuild.
Il SignalR client può essere aggiunto a un progetto CMake con il frammento di codice seguente quando vcpkg è incluso nel file toolchain:
find_package(microsoft-signalr CONFIG REQUIRED)
link_libraries(microsoft-signalr::microsoft-signalr)
Con il frammento di codice precedente, il SignalR client C++ è pronto per l'uso e l'uso #include
in un progetto senza alcuna configurazione aggiuntiva. Per un esempio completo di un'applicazione C++ che usa il SignalR client C++, vedere il repository halter73/SignalR-Client-Cpp-Sample .
Blazor
Modifiche al modello di progetto
Sono state apportate diverse modifiche al modello di progetto per Blazor le app, incluso l'uso del file per il Pages/_Layout.cshtml
contenuto del layout visualizzato nel _Host.cshtml
file per le app precedenti Blazor Server . Esaminare le modifiche creando un'app da un modello di progetto 6.0 o accedendo all'origine di riferimento ASP.NET Core per i modelli di progetto:
Blazor WebAssembly supporto delle dipendenze native
Blazor WebAssembly le app possono usare le dipendenze native create per l'esecuzione in WebAssembly. Per altre informazioni, vedere ASP.NET dipendenze native di CoreBlazor WebAssembly.
Compilazione e ricollegamento del runtime di WebAssembly Ahead-of-Time (AOT)
Blazor WebAssembly supporta la compilazione anticipata (AOT), in cui è possibile compilare il codice .NET direttamente in WebAssembly. La compilazione AOT comporta miglioramenti delle prestazioni di runtime a scapito di dimensioni maggiori dell'app. Il ricollegamento del runtime .NET WebAssembly riduce il codice di runtime inutilizzato e quindi migliora la velocità di download. Per altre informazioni, vedere Compilazione in anticipo (AOT) e Ricollegamento del runtime.
Mantenere lo stato prerenderato
Blazor supporta lo stato persistente in una pagina pre-risolto in modo che lo stato non debba essere ricreato quando l'app viene completamente caricata. Per altre informazioni, vedere Prerender and integrate ASP.NET Core components .For more information, see Prerender and integrate ASP.NET Core Razor components.
Limiti di errore
I limiti degli errori offrono un approccio pratico per la gestione delle eccezioni a livello di interfaccia utente. Per altre informazioni, vedere Gestire gli errori nelle app ASP.NET CoreBlazor.
Supporto SVG
L'elemento <foreignObject>
elemento è supportato per visualizzare codice HTML arbitrario in un formato SVG. Per altre informazioni, vedere ASP.NET Componenti di baseRazor.
Blazor Server supporto per il trasferimento di matrici di byte in JS Interoperabilità
Blazor supporta l'interoperabilità della matrice JS di byte ottimizzata che evita la codifica e la decodifica delle matrici di byte in Base64. Per ulteriori informazioni, vedi le seguenti risorse:
- Chiamare funzioni JavaScript da metodi .NET in ASP.NET Core Blazor
- Chiamare metodi .NET da funzioni JavaScript in ASP.NET Core Blazor
Miglioramenti delle stringhe di query
Il supporto per l'uso delle stringhe di query è stato migliorato. Per altre informazioni, vedere ASP.NET routing e navigazione coreBlazor.
Binding per selezionare più
L'associazione supporta la selezione di più opzioni con <input>
elementi. Per ulteriori informazioni, vedi le seguenti risorse:
Controllo contenuto head (<head>
)
Razor i componenti possono modificare il contenuto dell'elemento HTML <head>
di una pagina, inclusa l'impostazione del titolo della pagina (<title>
elemento) e la modifica dei metadati (<meta>
elementi). Per altre informazioni, vedere Controllare il <head>
contenuto nelle app ASP.NET CoreBlazor.
Generare componenti di Angular e React
Generare componenti JavaScript specifici del framework dai Razor componenti per framework Web, ad esempio Angular o React. Per altre informazioni, vedere ASP.NET Componenti di baseRazor.
Eseguire il rendering dei componenti di da JavaScript
Eseguire il rendering Razor di componenti in modo dinamico da JavaScript per le app JavaScript esistenti. Per altre informazioni, vedere ASP.NET Componenti di baseRazor.
Elementi personalizzati
Il supporto sperimentale è disponibile per la creazione di elementi personalizzati, che usano interfacce HTML standard. Per altre informazioni, vedere ASP.NET Componenti di baseRazor.
Dedurre i tipi generici dei componenti dai componenti predecessori
Un componente predecessore può propagare a catena un parametro di tipo in base al nome ai discendenti usando il nuovo [CascadingTypeParameter]
attributo. Per altre informazioni, vedere ASP.NET Componenti di baseRazor.
Componenti di cui è stato eseguito il rendering dinamico
Usare il nuovo componente predefinito DynamicComponent
per eseguire il rendering dei componenti in base al tipo. Per altre informazioni, vedere Componenti di base RazorASP.NET sottoposti a rendering dinamico.
Accessibilità migliorata Blazor
Usare il nuovo FocusOnNavigate
componente per impostare lo stato attivo dell'interfaccia utente su un elemento basato su un selettore CSS dopo lo spostamento da una pagina a un'altra. Per altre informazioni, vedere ASP.NET routing e navigazione coreBlazor.
Supporto dell'argomento evento personalizzato
Blazor supporta argomenti di evento personalizzati, che consentono di passare dati arbitrari ai gestori eventi .NET con eventi personalizzati. Per altre informazioni, vedere ASP.NET Gestione degli eventi CoreBlazor.
Parametri obbligatori
Applicare il nuovo [EditorRequired]
attributo per specificare un parametro del componente obbligatorio. Per altre informazioni, vedere ASP.NET Componenti di baseRazor.
Collocazione di file JavaScript con pagine, visualizzazioni e componenti
Collocare i file JavaScript per pagine, visualizzazioni e Razor componenti come modo pratico per organizzare gli script in un'app. Per altre informazioni, vedere ASP.NET Core JavaScript interoperabilità (interoperabilità).For more information, see ASP.NET Core Blazor JavaScript interoperability (JS interop).
Inizializzatori JavaScript
Gli inizializzatori JavaScript eseguono la logica prima e dopo il caricamento di un'app Blazor . Per altre informazioni, vedere ASP.NET Core JavaScript interoperabilità (interoperabilità).For more information, see ASP.NET Core Blazor JavaScript interoperability (JS interop).
Interoperabilità JavaScript di streaming
Blazor supporta ora lo streaming dei dati direttamente tra .NET e JavaScript. Per ulteriori informazioni, vedi le seguenti risorse:
Vincoli di tipo generico
I parametri di tipo generico sono ora supportati. Per altre informazioni, vedere ASP.NET Componenti di baseRazor.
Layout di distribuzione di WebAssembly
Usare un layout di distribuzione per abilitare Blazor WebAssembly i download delle app in ambienti di sicurezza con restrizioni. Per altre informazioni, vedere Layout di distribuzione per le app ospitate Blazor WebAssembly ASP.NET Core.
Nuovi Blazor articoli
Oltre alle Blazor funzionalità descritte nelle sezioni precedenti, sono disponibili nuovi Blazor articoli sugli argomenti seguenti:
- ASP.NET download di file coreBlazor: informazioni su come scaricare un file usando l'interoperabilità di streaming nativa
byte[]
per garantire un trasferimento efficiente al client. - Visualizzare immagini e documenti in ASP.NET Core Blazor: informazioni su come usare immagini e documenti nelle Blazor app, tra cui come trasmettere i dati di immagine e documento.
Creare Blazor Hybrid app con .NET MAUI, WPF e Windows Form
Usare Blazor Hybrid per combinare framework client nativi desktop e per dispositivi mobili con .NET e Blazor:
- .NET Multi-platform App UI (.NET MAUI) è un framework multipiattaforma per la creazione di app native per dispositivi mobili e desktop con C# e XAML.
- Blazor Hybridle app possono essere compilate con Windows Presentation Foundation (WPF) e Windows Form framework.
Importante
Blazor Hybrid è in anteprima e non deve essere usato nelle app di produzione fino alla versione finale.
Per ulteriori informazioni, vedi le seguenti risorse:
- Documentazione di ASP.NET Core Blazor Hybrid in anteprima
- Che cos'è .NET MAUI?
- Blog di Microsoft .NET (categoria: ".NET MAUI")
Kestrel
HTTP/3 è attualmente in fase di bozza e quindi soggetto a modifiche. Il supporto HTTP/3 in ASP.NET Core non viene rilasciato, è una funzionalità di anteprima inclusa in .NET 6.
Kestrel supporta ora HTTP/3. Per altre informazioni, vedere Usare HTTP/3 con il server Web ASP.NET Core Kestrel e il post di blog http/3 support in .NET 6.
Nuove Kestrel categorie di registrazione per la registrazione selezionata
Prima di questa modifica, l'abilitazione della registrazione dettagliata per Kestrel è stata eccessivamente costosa come tutti i nomi della categoria di Kestrel registrazione condivisa Microsoft.AspNetCore.Server.Kestrel
. Microsoft.AspNetCore.Server.Kestrel
è ancora disponibile, ma le nuove sottocategorie seguenti consentono un maggiore controllo della registrazione:
Microsoft.AspNetCore.Server.Kestrel
(categoria corrente):ApplicationError
,ConnectionHeadResponseBodyWrite
ApplicationNeverCompleted
, ,RequestBodyStart
RequestBodyDone
,RequestBodyNotEntirelyRead
,RequestBodyDrainTimedOut
,ResponseMinimumDataRateNotSatisfied
,InvalidResponseHeaderRemoved
HeartbeatSlow
.Microsoft.AspNetCore.Server.Kestrel.BadRequests
:ConnectionBadRequest
,RequestProcessingError
,RequestBodyMinimumDataRateNotSatisfied
.Microsoft.AspNetCore.Server.Kestrel.Connections
:ConnectionAccepted
,ConnectionStart
,ConnectionStop
,ConnectionPause
ConnectionResume
,ConnectionKeepAlive
,ConnectionRejected
ConnectionDisconnect
, ,NotAllConnectionsClosedGracefully
,NotAllConnectionsAborted
.ApplicationAbortedConnection
Microsoft.AspNetCore.Server.Kestrel.Http2
:Http2ConnectionError
,Http2ConnectionClosing
,Http2ConnectionClosed
,Http2StreamError
Http2StreamResetAbort
,HPackDecodingError
Http2FrameReceived
HPackEncodingError
, .Http2FrameSending
Http2MaxConcurrentStreamsReached
Microsoft.AspNetCore.Server.Kestrel.Http3
:Http3ConnectionError
,Http3ConnectionClosing
,Http3ConnectionClosed
Http3StreamAbort
,Http3FrameReceived
, , .Http3FrameSending
Le regole esistenti continuano a funzionare, ma è ora possibile essere più selettive sulle regole abilitate. Ad esempio, l'overhead di osservabilità dell'abilitazione Debug
della registrazione per richieste non valide è notevolmente ridotto e può essere abilitato con la configurazione seguente:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.Kestrel.BadRequests": "Debug"
}
}
Il filtro dei log applica regole con il prefisso della categoria corrispondente più lungo. Per altre informazioni, vedere Come vengono applicate le regole di filtro
Generare KestrelServerOptions tramite l'evento EventSource
KestrelEventSource genera un nuovo evento contenente il codice JSON serializzato KestrelServerOptions quando è abilitato con dettaglio EventLevel.LogAlways
. Questo evento semplifica il motivo del comportamento del server durante l'analisi delle tracce raccolte. Il codice JSON seguente è un esempio del payload dell'evento:
{
"AllowSynchronousIO": false,
"AddServerHeader": true,
"AllowAlternateSchemes": false,
"AllowResponseHeaderCompression": true,
"EnableAltSvc": false,
"IsDevCertLoaded": true,
"RequestHeaderEncodingSelector": "default",
"ResponseHeaderEncodingSelector": "default",
"Limits": {
"KeepAliveTimeout": "00:02:10",
"MaxConcurrentConnections": null,
"MaxConcurrentUpgradedConnections": null,
"MaxRequestBodySize": 30000000,
"MaxRequestBufferSize": 1048576,
"MaxRequestHeaderCount": 100,
"MaxRequestHeadersTotalSize": 32768,
"MaxRequestLineSize": 8192,
"MaxResponseBufferSize": 65536,
"MinRequestBodyDataRate": "Bytes per second: 240, Grace Period: 00:00:05",
"MinResponseDataRate": "Bytes per second: 240, Grace Period: 00:00:05",
"RequestHeadersTimeout": "00:00:30",
"Http2": {
"MaxStreamsPerConnection": 100,
"HeaderTableSize": 4096,
"MaxFrameSize": 16384,
"MaxRequestHeaderFieldSize": 16384,
"InitialConnectionWindowSize": 131072,
"InitialStreamWindowSize": 98304,
"KeepAlivePingDelay": "10675199.02:48:05.4775807",
"KeepAlivePingTimeout": "00:00:20"
},
"Http3": {
"HeaderTableSize": 0,
"MaxRequestHeaderFieldSize": 16384
}
},
"ListenOptions": [
{
"Address": "https://127.0.0.1:7030",
"IsTls": true,
"Protocols": "Http1AndHttp2"
},
{
"Address": "https://[::1]:7030",
"IsTls": true,
"Protocols": "Http1AndHttp2"
},
{
"Address": "http://127.0.0.1:5030",
"IsTls": false,
"Protocols": "Http1AndHttp2"
},
{
"Address": "http://[::1]:5030",
"IsTls": false,
"Protocols": "Http1AndHttp2"
}
]
}
Nuovo evento DiagnosticSource per le richieste HTTP rifiutate
Kestrel ora genera un nuovo DiagnosticSource
evento per le richieste HTTP rifiutate a livello di server. Prima di questa modifica, non è stato possibile osservare queste richieste rifiutate. Il nuovo DiagnosticSource
evento Microsoft.AspNetCore.Server.Kestrel.BadRequest
contiene un IBadRequestExceptionFeature oggetto che può essere utilizzato per introspettire il motivo per rifiutare la richiesta.
using Microsoft.AspNetCore.Http.Features;
using System.Diagnostics;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var diagnosticSource = app.Services.GetRequiredService<DiagnosticListener>();
using var badRequestListener = new BadRequestEventListener(diagnosticSource,
(badRequestExceptionFeature) =>
{
app.Logger.LogError(badRequestExceptionFeature.Error, "Bad request received");
});
app.MapGet("/", () => "Hello world");
app.Run();
class BadRequestEventListener : IObserver<KeyValuePair<string, object>>, IDisposable
{
private readonly IDisposable _subscription;
private readonly Action<IBadRequestExceptionFeature> _callback;
public BadRequestEventListener(DiagnosticListener diagnosticListener,
Action<IBadRequestExceptionFeature> callback)
{
_subscription = diagnosticListener.Subscribe(this!, IsEnabled);
_callback = callback;
}
private static readonly Predicate<string> IsEnabled = (provider) => provider switch
{
"Microsoft.AspNetCore.Server.Kestrel.BadRequest" => true,
_ => false
};
public void OnNext(KeyValuePair<string, object> pair)
{
if (pair.Value is IFeatureCollection featureCollection)
{
var badRequestFeature = featureCollection.Get<IBadRequestExceptionFeature>();
if (badRequestFeature is not null)
{
_callback(badRequestFeature);
}
}
}
public void OnError(Exception error) { }
public void OnCompleted() { }
public virtual void Dispose() => _subscription.Dispose();
}
Per altre informazioni, vedere Registrazione e diagnostica in Kestrel.
Creare un connectionContext da un socket accept
Il nuovo SocketConnectionContextFactory rende possibile creare un oggetto ConnectionContext da un socket accettato. In questo modo è possibile creare un socket personalizzato senza IConnectionListenerFactory perdere tutte le prestazioni e il pooling in SocketConnection.
Vedere questo esempio di un oggetto IConnectionListenerFactory personalizzato che illustra come usare questo SocketConnectionContextFactory
oggetto .
Kestrel è il profilo di avvio predefinito per Visual Studio
Il profilo di avvio predefinito per tutti i nuovi progetti Web dotnet è Kestrel. L'avvio Kestrel è notevolmente più veloce e comporta un'esperienza più reattiva durante lo sviluppo di app.
IIS Express è ancora disponibile come profilo di avvio per scenari come l'autenticazione di Windows o la condivisione delle porte.
Le porte Localhost per Kestrel sono casuali
Per altre informazioni, vedere Porte generate dal modello per Kestrel in questo documento.
Autenticazione e autorizzazione
Server di autenticazione
.NET 3 a .NET 5 ha usato IdentityServer4 come parte del modello per supportare l'emissione di token JWT per spa e Blazor applicazioni. I modelli ora usano il server DuendeIdentity.
Se si estendono i identity modelli e si aggiornano i progetti esistenti, aggiornare gli spazi dei nomi nel codice da IdentityServer4.IdentityServer
a Duende.IdentityServer
e seguire le istruzioni di migrazione.
Il modello di licenza per Duende Identity Server è cambiato in una licenza reciproca, che può richiedere tariffe di licenza quando viene usato commercialmente nell'ambiente di produzione. Per altri dettagli, vedere la pagina delle licenze di Duende.
Negoziazione del certificato client ritardata
Gli sviluppatori possono ora acconsentire esplicitamente all'uso della negoziazione del certificato client ritardata specificando ClientCertificateMode.DelayCertificate in HttpsConnectionAdapterOptions. Questo funziona solo con le connessioni HTTP/1.1 perché HTTP/2 impedisce la rinegoziazione dei certificati ritardata. Il chiamante di questa API deve memorizzare il corpo della richiesta nel buffer prima di richiedere il certificato client:
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.AspNetCore.WebUtilities;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel(options =>
{
options.ConfigureHttpsDefaults(adapterOptions =>
{
adapterOptions.ClientCertificateMode = ClientCertificateMode.DelayCertificate;
});
});
var app = builder.Build();
app.Use(async (context, next) =>
{
bool desiredState = GetDesiredState();
// Check if your desired criteria is met
if (desiredState)
{
// Buffer the request body
context.Request.EnableBuffering();
var body = context.Request.Body;
await body.DrainAsync(context.RequestAborted);
body.Position = 0;
// Request client certificate
var cert = await context.Connection.GetClientCertificateAsync();
// Disable buffering on future requests if the client doesn't provide a cert
}
await next(context);
});
app.MapGet("/", () => "Hello World!");
app.Run();
OnCheckSlidingExpiration
evento per il controllo del cookie rinnovo
Cookie La scadenza scorrevole dell'autenticazione può ora essere personalizzata o eliminata usando il nuovo OnCheckSlidingExpirationoggetto . Ad esempio, questo evento può essere usato da un'app a pagina singola che deve effettuare periodicamente il ping del server senza influire sulla sessione di autenticazione.
Varie
Ricaricamento rapido
Apportare rapidamente aggiornamenti dell'interfaccia utente e del codice alle app in esecuzione senza perdere lo stato dell'app per un'esperienza di sviluppo più veloce e produttiva usando Ricaricamento rapido. Per altre informazioni, vedere Supporto di .NET Ricaricamento rapido per ASP.NET Core e aggiornamento in .NET Ricaricamento rapido avanzamento e Evidenziazioni di Visual Studio 2022.
Modelli di app a pagina singola migliorati
I modelli di progetto ASP.NET Core sono stati aggiornati per Angular e React per usare un modello migliorato per le app a pagina singola più flessibili e più strettamente allineate ai modelli comuni per lo sviluppo Web front-end moderno.
In precedenza, il modello ASP.NET Core per Angular e React usava middleware specializzato durante lo sviluppo per avviare il server di sviluppo per il framework front-end e quindi le richieste proxy da ASP.NET Core al server di sviluppo. La logica per l'avvio del server di sviluppo front-end era specifica dell'interfaccia della riga di comando per il framework front-end corrispondente. Il supporto di framework front-end aggiuntivi che usano questo modello significava aggiungere logica aggiuntiva a ASP.NET Core.
I modelli di ASP.NET Core aggiornati per Angular e React in .NET 6 capovolgono questa disposizione e sfruttano il supporto predefinito del proxy nei server di sviluppo dei framework front-end più moderni. Quando viene avviata l'app ASP.NET Core, il server di sviluppo front-end viene avviato esattamente come in precedenza, ma il server di sviluppo è configurato per il proxy delle richieste al processo back-end ASP.NET Core. Tutte le configurazioni specifiche del front-end per configurare il proxy fanno parte dell'app, non ASP.NET Core. La configurazione di ASP.NET progetti Core per l'uso con altri framework front-end è ora semplice: configurare il server di sviluppo front-end per il framework scelto per il proxy al back-end ASP.NET Core usando il modello stabilito nei modelli Angular e React.
Il codice di avvio per l'app ASP.NET Core non richiede più alcuna logica specifica dell'app a pagina singola. La logica per avviare il server di sviluppo front-end durante lo sviluppo viene inserita nell'app in fase di esecuzione dal nuovo pacchetto Microsoft.AspNetCore.SpaProxy . Il routing di fallback viene gestito usando il routing degli endpoint anziché il middleware specifico dell'applicazione a pagina singola.
I modelli che seguono questo modello possono comunque essere eseguiti come un singolo progetto in Visual Studio o usando dotnet run
dalla riga di comando. Quando l'app viene pubblicata, il codice front-end nella cartella ClientApp viene compilato e raccolto come prima nella radice Web dell'app host ASP.NET Core e servito come file statici. Gli script inclusi nel modello configurano il server di sviluppo front-end per l'uso di HTTPS usando il certificato di sviluppo ASP.NET Core.
Supporto http/3 bozza in .NET 6
HTTP/3 è attualmente in fase di bozza e quindi soggetto a modifiche. Il supporto HTTP/3 in ASP.NET Core non viene rilasciato, è una funzionalità di anteprima inclusa in .NET 6.
Vedere la voce di blog supporto HTTP/3 in .NET 6.
Annotazioni del tipo riferimento nullable
Parti del codice sorgente di ASP.NET Core 6.0 hanno applicato annotazioni di nullità.
Usando la nuova funzionalità Nullable in C# 8, ASP.NET Core può fornire ulteriore sicurezza in fase di compilazione nella gestione dei tipi di riferimento. Ad esempio, la protezione da null
eccezioni di riferimento. I progetti che hanno acconsento esplicitamente all'uso di annotazioni nullable possono visualizzare nuovi avvisi in fase di compilazione dalle API di base di ASP.NET.
Per abilitare i tipi riferimento nullable, aggiungere la proprietà seguente ai file di progetto:
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
Per altre informazioni, vedere Tipi di riferimento Nullable.
Analisi del codice sorgente
Sono stati aggiunti diversi analizzatori della piattaforma del compilatore .NET che esaminano il codice dell'applicazione per individuare problemi quali la configurazione o l'ordine del middleware non corretto, i conflitti di routing e così via. Per altre informazioni, vedere Analisi del codice nelle app ASP.NET Core.
Miglioramenti del modello di app Web
Modelli di app Web:
- Usare il nuovo modello di hosting minimo.
- Riduce significativamente il numero di file e righe di codice necessari per creare un'app. Ad esempio, l'app Web vuota ASP.NET Core crea un file C# con quattro righe di codice ed è un'app completa.
- Unifica
Startup.cs
eProgram.cs
in un singoloProgram.cs
file. - Usa istruzioni di primo livello per ridurre al minimo il codice necessario per un'app.
- Usa direttive globali
using
per eliminare o ridurre al minimo il numero di righe diusing
istruzioni necessarie.
Porte generate dal modello per Kestrel
Le porte casuali vengono assegnate durante la creazione del progetto per l'uso da parte del Kestrel server Web. Le porte casuali consentono di ridurre al minimo un conflitto di porte quando più progetti vengono eseguiti nello stesso computer.
Quando viene creato un progetto, nel file generato Properties/launchSettings.json
viene specificata una porta HTTP casuale compresa tra 5000-5300 e una porta HTTPS casuale compresa tra 7000 e 7300. Le porte possono essere modificate nel Properties/launchSettings.json
file. Se non viene specificata alcuna porta, Kestrel per impostazione predefinita le porte HTTP 5000 e HTTPS 5001. Per altre informazioni, vedere Configurare gli endpoint per il server Web ASP.NET CoreKestrel.
Nuove impostazioni predefinite di registrazione
Sono state apportate le modifiche seguenti a appsettings.json
e appsettings.Development.json
:
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"
La modifica da "Microsoft": "Warning"
a "Microsoft.AspNetCore": "Warning"
comporta la registrazione di tutti i messaggi informativi dallo spazio dei Microsoft
nomi ad eccezione Microsoft.AspNetCore
di . Ad esempio, Microsoft.EntityFrameworkCore
viene registrato a livello informativo.
Middleware per le eccezioni per sviluppatori aggiunto automaticamente
Nell'ambiente di sviluppo l'oggetto DeveloperExceptionPageMiddleware viene aggiunto per impostazione predefinita. Non è più necessario aggiungere il codice seguente alle app dell'interfaccia utente Web:
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
Supporto per le intestazioni di richiesta con codifica Latin1 in HttpSysServer
HttpSysServer
supporta ora la decodifica delle intestazioni Latin1
di richiesta codificate impostando la UseLatin1RequestHeaders proprietà su HttpSysOptions true
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys(o => o.UseLatin1RequestHeaders = true);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
I log di ASP.NET Core Module includono timestamp e PID
I log di diagnostica avanzati di ASP.NET Core Module (ANCM) per IIS (ANCM) includono timestamp e PID del processo che genera i log. La registrazione di timestamp e PID semplifica la diagnosi dei problemi relativi ai riavvii di processi sovrapposti in IIS quando sono in esecuzione più processi di lavoro IIS.
I log risultanti sono ora simili all'output di esempio illustrato di seguito:
[2021-07-28T19:23:44.076Z, PID: 11020] [aspnetcorev2.dll] Initializing logs for 'C:\<path>\aspnetcorev2.dll'. Process Id: 11020. File Version: 16.0.21209.0. Description: IIS ASP.NET Core Module V2. Commit: 96475a2acdf50d7599ba8e96583fa73efbe27912.
[2021-07-28T19:23:44.079Z, PID: 11020] [aspnetcorev2.dll] Resolving hostfxr parameters for application: '.\InProcessWebSite.exe' arguments: '' path: 'C:\Temp\e86ac4e9ced24bb6bacf1a9415e70753\'
[2021-07-28T19:23:44.080Z, PID: 11020] [aspnetcorev2.dll] Known dotnet.exe location: ''
Configurabile le dimensioni del buffer in ingresso non consumate per IIS
Il server IIS in precedenza memorizzava nel buffer solo 64 KiB di corpi di richiesta non utilizzati. Il buffering di 64 KiB ha comportato un vincolo di lettura a tale dimensione massima, che influisce sulle prestazioni con corpi in ingresso di grandi dimensioni, ad esempio i caricamenti. In .NET 6 le dimensioni predefinite del buffer cambiano da 64 KiB a 1 MiB, che dovrebbe migliorare la velocità effettiva per caricamenti di grandi dimensioni. Nei test, un caricamento miB di 700 che richiedeva 9 secondi ora richiede solo 2,5 secondi.
Lo svantaggio di una dimensione del buffer maggiore è un aumento del consumo di memoria per richiesta quando l'app non legge rapidamente dal corpo della richiesta. Oltre a modificare le dimensioni predefinite del buffer, la dimensione del buffer configurabile, consentendo alle app di configurare le dimensioni del buffer in base al carico di lavoro.
Visualizzare gli helper tag dei componenti
Si consideri un componente di visualizzazione con un parametro facoltativo, come illustrato nel codice seguente:
class MyViewComponent
{
IViewComponentResult Invoke(bool showSomething = false) { ... }
}
Con ASP.NET Core 6, l'helper tag può essere richiamato senza dover specificare un valore per il showSomething
parametro :
<vc:my />
Modello Angular aggiornato a Angular 12
Il modello ASP.NET Core 6.0 per Angular usa ora Angular 12.
Il modello React è stato aggiornato a React 17.
Soglia del buffer configurabile prima della scrittura su disco in Json.NET formattatore di output
Nota: è consigliabile usare il System.Text.Json formattatore di output tranne quando il Newtonsoft.Json
serializzatore è necessario per motivi di compatibilità. Il System.Text.Json
serializzatore è completamente async
e funziona in modo efficiente per payload più grandi.
Il Newtonsoft.Json
formattatore di output per impostazione predefinita memorizza nel buffer le risposte fino a 32 KiB in memoria prima del buffering su disco. Ciò consiste nell'evitare di eseguire operazioni di I/O sincrone, che possono comportare altri effetti collaterali, ad esempio la fame di thread e i deadlock dell'applicazione. Tuttavia, se la risposta è superiore a 32 KiB, si verifica una notevole I/O su disco. La soglia di memoria è ora configurabile tramite la proprietà MvcNewtonsoftJsonOptions.OutputFormatterMemoryBufferThreshold prima del buffering su disco:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages()
.AddNewtonsoftJson(options =>
{
options.OutputFormatterMemoryBufferThreshold = 48 * 1024;
});
var app = builder.Build();
Per altre informazioni, vedere questa richiesta pull di GitHub e il file NewtonsoftJsonOutputFormatterTest.cs .
Ottenere e impostare più velocemente per le intestazioni HTTP
Sono state aggiunte nuove API per esporre tutte le intestazioni comuni disponibili in Microsoft.Net.Http.Headers.HeaderNames come proprietà sul IHeaderDictionary risultato in un'API più semplice da usare. Ad esempio, il middleware inline nel codice seguente ottiene e imposta intestazioni di richiesta e risposta usando le nuove API:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Use(async (context, next) =>
{
var hostHeader = context.Request.Headers.Host;
app.Logger.LogInformation("Host header: {host}", hostHeader);
context.Response.Headers.XPoweredBy = "ASP.NET Core 6.0";
await next.Invoke(context);
var dateHeader = context.Response.Headers.Date;
app.Logger.LogInformation("Response date: {date}", dateHeader);
});
app.Run();
Per le intestazioni implementate, le funzioni di accesso get e set vengono implementate passando direttamente al campo e ignorando la ricerca. Per le intestazioni non implementate, le funzioni di accesso possono ignorare la ricerca iniziale rispetto alle intestazioni implementate ed eseguire direttamente la Dictionary<string, StringValues>
ricerca. Evitare la ricerca comporta un accesso più rapido per entrambi gli scenari.
Streaming asincrono
ASP.NET Core supporta ora lo streaming asincrono dalle azioni e dalle risposte del controller dal formattatore JSON. La restituzione di un oggetto IAsyncEnumerable
da un'azione non memorizza più nel buffer il contenuto della risposta in memoria prima dell'invio. La mancata memorizzazione nel buffer consente di ridurre l'utilizzo della memoria quando si restituiscono set di dati di grandi dimensioni che possono essere enumerati in modo asincrono.
Si noti che Entity Framework Core fornisce implementazioni di per l'esecuzione di IAsyncEnumerable
query sul database. Il supporto migliorato per IAsyncEnumerable
in ASP.NET Core in .NET 6 può essere usato EF Core con ASP.NET Core più efficiente. Ad esempio, il codice seguente non memorizza più nel buffer i dati del prodotto in memoria prima di inviare la risposta:
public IActionResult GetMovies()
{
return Ok(_context.Movie);
}
Tuttavia, quando si usa il caricamento differita in EF Core, questo nuovo comportamento può causare errori a causa dell'esecuzione simultanea delle query durante l'enumerazione dei dati. Le app possono ripristinare il comportamento precedente memorizzando nel buffer i dati:
public async Task<IActionResult> GetMovies2()
{
return Ok(await _context.Movie.ToListAsync());
}
Per altri dettagli su questa modifica nel comportamento, vedere l'annuncio correlato.
Middleware di registrazione HTTP
La registrazione HTTP è un nuovo middleware predefinito che registra le informazioni sulle richieste HTTP e le risposte HTTP, incluse le intestazioni e l'intero corpo:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpLogging();
app.MapGet("/", () => "Hello World!");
app.Run();
Passare a /
con le informazioni di log del codice precedenti simili all'output seguente:
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
Request:
Protocol: HTTP/2
Method: GET
Scheme: https
PathBase:
Path: /
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: max-age=0
Connection: close
Cookie: [Redacted]
Host: localhost:44372
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30
sec-ch-ua: [Redacted]
sec-ch-ua-mobile: [Redacted]
sec-ch-ua-platform: [Redacted]
upgrade-insecure-requests: [Redacted]
sec-fetch-site: [Redacted]
sec-fetch-mode: [Redacted]
sec-fetch-user: [Redacted]
sec-fetch-dest: [Redacted]
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
Response:
StatusCode: 200
Content-Type: text/plain; charset=utf-8
L'output precedente è stato abilitato con il file seguente appsettings.Development.json
:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
}
}
}
La registrazione HTTP fornisce log per:
- Informazioni sulla richiesta HTTP
- Proprietà comuni
- Intestazioni
- Testo
- Informazioni sulla risposta HTTP
Per configurare il middleware di registrazione HTTP, specificare HttpLoggingOptions:
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
// Customize HTTP logging.
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("My-Request-Header");
logging.ResponseHeaders.Add("My-Response-Header");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
app.UseHttpLogging();
app.MapGet("/", () => "Hello World!");
app.Run();
IConnectionSocketFeature
La IConnectionSocketFeature funzionalità di richiesta fornisce l'accesso al socket accept sottostante associato alla richiesta corrente. È possibile accedervi tramite su FeatureCollection HttpContext
.
Ad esempio, l'app seguente imposta la LingerState proprietà sul socket accettato:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions => listenOptions.Use((connection, next) =>
{
var socketFeature = connection.Features.Get<IConnectionSocketFeature>();
socketFeature.Socket.LingerState = new LingerOption(true, seconds: 10);
return next();
}));
});
var app = builder.Build();
app.MapGet("/", (Func<string>)(() => "Hello world"));
await app.RunAsync();
Vincoli di tipo generico in Razor
Quando si definiscono parametri di tipo generico in Razor usando la @typeparam
direttiva , è ora possibile specificare vincoli di tipo generico usando la sintassi C# standard:
Script , Blazor Servere MessagePack più piccoli SignalR
Gli SignalRscript , MessagePack e Blazor Server sono ora notevolmente più piccoli, consentendo download più piccoli, meno analisi e compilazione JavaScript dal browser e avvio più rapido. Riduzione delle dimensioni:
signalr.js
: 70%blazor.server.js
: 45%
Gli script più piccoli sono il risultato di un contributo della community di Ben Adams. Per altre informazioni sui dettagli della riduzione delle dimensioni, vedere La richiesta pull di GitHub di Ben.
Abilitare le sessioni di profilatura di Redis
Un contributo della community di Gabriel Lucaci abilita la sessione di profilatura di Redis con Microsoft.Extensions.Caching.StackExchangeRedis:
using StackExchange.Redis.Profiling;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddStackExchangeRedisCache(options =>
{
options.ProfilingSession = () => new ProfilingSession();
});
Per altre informazioni, vedere Profiling stackExchange.Redis.
Copia shadow in IIS
È stata aggiunta una funzionalità sperimentale all'ASP.NET Core Module (ANCM) per IIS per aggiungere il supporto per gli assembly dell'applicazione di copia shadow. Attualmente .NET blocca i file binari dell'applicazione durante l'esecuzione in Windows, rendendo impossibile sostituire i file binari quando l'app è in esecuzione. Anche se il consiglio rimane di usare un file offline dell'app, è possibile riconoscere che esistono alcuni scenari (ad esempio distribuzioni FTP) in cui non è possibile farlo.
In questi scenari, abilitare la copia shadow personalizzando le impostazioni del gestore del modulo core di ASP.NET. Nella maggior parte dei casi, ASP.NET le app Core non dispongono di un web.config
controllo del codice sorgente che è possibile modificare. In ASP.NET Core, web.config
viene in genere generato dall'SDK. Per iniziare, è possibile usare l'esempio web.config
seguente:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- To customize the asp.net core module uncomment and edit the following section.
For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
<system.webServer>
<handlers>
<remove name="aspNetCore"/>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
<handlerSettings>
<handlerSetting name="experimentalEnableShadowCopy" value="true" />
<handlerSetting name="shadowCopyDirectory" value="../ShadowCopyDirectory/" />
<!-- Only enable handler logging if you encounter issues-->
<!--<handlerSetting name="debugFile" value=".\logs\aspnetcore-debug.log" />-->
<!--<handlerSetting name="debugLevel" value="FILE,TRACE" />-->
</handlerSettings>
</aspNetCore>
</system.webServer>
</configuration>
La copia shadow in IIS è una funzionalità sperimentale che non è garantita come parte di ASP.NET Core. Lasciare commenti e suggerimenti sulla copia shadow di IIS in questo problema di GitHub.