ASP.NET Core 6.0 的新功能

本文強調 ASP.NET Core 6.0 中最重要的變更,其中包含相關檔的連結。

ASP.NET Core MVC 和 Razor 改善

最小 API

最少的 API 會建構為建立具有最少相依性的 HTTP API。 它們非常適合微服務和應用程式,這些微服務和應用程式只想要在 ASP.NET Core中包含最小檔案、功能和相依性。 如需詳細資訊,請參閱

SignalR

連線長時間執行的啟動磁碟區標 SignalR

SignalR 會使用 新的 Microsoft.AspNetCore.Http.Features.IHttpActivityFeature.Activity ,將標記新增 http.long_running 至要求活動。 IHttpActivityFeature.ActivityAPM 服務會使用Azure 監視器應用程式Insights來篩選 SignalR 要求,以建立長時間執行的要求警示。

SignalR 效能改善

  • 為每個連線配置 HubCallerClients 一次,而不是每個中樞方法呼叫。
  • 避免 在 中 SignalRDefaultHubDispatcher.Invoke 關閉配置。 狀態會透過參數傳遞至本機靜態函式,以避免關閉配置。 如需詳細資訊,請參閱此GitHub提取要求
  • 在伺服器對用戶端串流中配置單 StreamItemMessage 一資料流程,而不是每個資料流程專案。 如需詳細資訊,請參閱此GitHub提取要求

Razor 編譯 器

Razor 編譯器已更新為使用來源產生器

編譯 Razor 程式現在以 C# 來源產生器為基礎。 來源產生器會在編譯期間執行,並檢查正在編譯的內容,以產生與其他專案一起編譯的其他檔案。 使用來源產生器可 Razor 簡化編譯器,並大幅加快建置時間。

Razor 編譯器不再產生個別的 Views 元件

編譯 Razor 程式先前使用雙步驟編譯器,其會產生個別的 Views 元件,其中包含產生的檢視和頁面, (.cshtml 應用程式中定義的檔案) 。 產生的型別是公用的,而且在 AspNetCore 命名空間下。

更新 Razor 的編譯器會將檢視和頁面類型建置到主要專案元件中。 這些類型現在預設會產生為命名空間中的 AspNetCoreGeneratedDocument 內部密封。 這項變更可改善組建效能、啟用單一檔案部署,並讓這些類型參與熱重新載入

如需這項變更的詳細資訊,請參閱GitHub的相關公告問題

ASP.NET Core效能和 API 改善

許多變更是為了減少配置並改善整個堆疊的效能:

降低閒置 TLS 連線的記憶體使用量

針對長時間執行的 TLS 連線,其中資料只會來回傳送,我們已大幅減少 .NET 6 中 ASP.NET Core應用程式的記憶體使用量。 這應該有助於改善 WebSocket 伺服器等案例的延展性。 這可能是因為 、 SslStream 和 Kestrel 中的 System.IO.Pipelines 許多改善。 下列各節詳述一些已降低記憶體使用量的改善:

減少 的大小 System.IO.Pipelines.Pipe

針對所建立的每個連線,會在 中 Kestrel 配置兩個管道:

  • 要求之應用程式的傳輸層。
  • 回應的傳輸應用層。

藉由將 大小 System.IO.Pipelines.Pipe 從 368 個位元組壓縮為 264 個位元組, (大約減少 28.2%) ,每個連線會儲存 208 個位元組, (每個管道) 104 個位元組。

集區 SocketSender

SocketSender 物件 (,子類別 SocketAsyncEventArgs) 執行時間大約是 350 個位元組。 您可以進行集區,而不是為每個連線配置新的 SocketSender 物件。 SocketSender 物件可以集區化,因為傳送速度通常非常快。 共用可減少每個連線的額外負荷。 不會配置每個連線 350 個位元組,而是只配置每個 IOQueue 350 個位元組。 每個佇列的配置都是為了避免爭用而完成。 具有 5000 個閒置連線的 WebSocket 伺服器從配置 ~1.75 MB (350 位元組 * 5000 個) 配置至配置 ~2.8 kb (350 個位元組 * 8 個物件) SocketSender

使用 SslStream 讀取零個位元組

無緩衝讀取是 ASP.NET Core採用的技術,以避免在通訊端上沒有可用的資料時,從記憶體集區租用記憶體。 在這項變更之前,我們的 WebSocket 伺服器需要 5000 個閒置連線 ~200 MB,而不需要 TLS,而與 TLS 相較之下為 ~800 MB。 其中一些配置 (每個連線) 4k,就是在 Kestrel 等候讀取 SslStream 完成時必須按住 ArrayPool<T> 緩衝區。 假設這些連線閒置,所以不會完成任何讀取,並將緩衝區傳回給 ArrayPool ,強制 配置 ArrayPool 更多記憶體。 其餘配置本身為 SslStream :TLS 交握的 4k 緩衝區,以及一般讀取的 32k 緩衝區。 在 .NET 6 中,當使用者在 上 SslStream 執行零位元組讀取且沒有可用的資料時, SslStream 會在內部對基礎包裝資料流程執行零位元組讀取。 在最佳情況下, (閒置連線) ,這些變更會導致每個連線節省 40 Kb,同時仍允許取用者 (Kestrel) 在資料可用時收到通知,而不需保留任何未使用的緩衝區。

使用 PipeReader 的零位元組讀取

在 上 SslStream 支援無緩衝讀取時,已新增一個選項,以對 執行零位元組讀取 StreamPipeReader ,而內部類型會將 調整 StreamPipeReader 。 在 中 Kestrel , StreamPipeReader 是用來將基礎 SslStream 調整為 PipeReader 。 因此,必須在 上 PipeReader 公開這些零位元組讀取語意。

PipeReader現在,可以使用下列 API,在支援零位元組讀取語意的任何基礎 Stream 上,建立 支援零位元組讀取語意 (的 ,例如 SslStreamNetworkStream 等) :

var reader = PipeReader.Create(stream, new StreamPipeReaderOptions(useZeroByteReads: true));

從 移除平板 SlabMemoryPool

為了減少堆積的片段,會採用一種技術, Kestrel 在其中將 128 KB 的記憶板配置為其記憶體集區的一部分。 然後,平板會進一步分成內部使用的 Kestrel 4 KB 區塊。 平板必須大於 85 KB,才能強制配置大型物件堆積,以嘗試並防止 GC 重新放置此陣列。 不過,隨著引進新的 GC 產生, 釘選物件堆積 (POH) ,就不再合理地在平板上配置區塊。 Kestrel 現在會直接在 POH 上配置區塊,以減少管理記憶體集區所涉及的複雜度。 這項變更應該更容易執行未來的改善,例如,更容易壓縮 所使用的 Kestrel 記憶體集區。

支援 IAsyncDisposable

IAsyncDisposable 現在適用于控制器、 Razor 頁面和檢視元件。 非同步版本已新增至處理站和啟動程式的相關介面:

  • 新的方法提供預設介面實作,委派給同步版本並呼叫 Dispose
  • 實作會覆寫預設實作並處理處置 IAsyncDisposable 實作。
  • 實作會優先 IAsyncDisposableIDisposable 實作這兩個介面時。
  • 擴充器必須覆寫包含以支援 IAsyncDisposable 實例的新方法。

IAsyncDisposable 使用時會很有説明:

  • 例如,非同步資料流程中的非同步列舉值。
  • 具有需要大量資源 I/O 作業釋放的 Unmanaged 資源。

實作此介面時,請使用 DisposeAsync 方法來釋放資源。

請考慮建立和使用 的 Utf8JsonWriter 控制器。 Utf8JsonWriter 是資源 IAsyncDisposable

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 必須實作 DisposeAsync

public async ValueTask DisposeAsync()
{
    if (_jsonWriter is not null)
    {
        await _jsonWriter.DisposeAsync();
    }

    _jsonWriter = null;
}

C++ 用戶端的 SignalR Vcpkg 埠

Vcpkg 是適用于 C 和 C++ 程式庫的跨平臺命令列套件管理員。 我們最近已將 埠新增至 , vcpkg 以新增 CMake C++ 用戶端的 SignalR 原生支援。 vcpkg也適用于MSBuild。

SignalR當工具鏈檔案中包含vcpkg時,用戶端可以新增至具有下列程式碼片段的 CMake 專案:

find_package(microsoft-signalr CONFIG REQUIRED)
link_libraries(microsoft-signalr::microsoft-signalr)

使用上述程式碼片段時, SignalR C++ 用戶端已準備好在專案中使用 #include 及使用,而不需要任何其他組態。 如需使用 SignalR C++ 用戶端之 C++ 應用程式的完整範例,請參閱 halter73/ SignalR -Client-Cpp-Sample 存放庫。

Blazor

Blazor WebAssembly 原生相依性支援

Blazor WebAssembly 應用程式可以使用建置在 WebAssembly 上執行的原生相依性。 如需詳細資訊,請參閱ASP.NET Core Blazor WebAssembly 原生相依性

WebAssembly 預先 (AOT) 編譯和執行時間重新連結

Blazor WebAssembly 支援預先 (AOT) 編譯,您可以在其中直接將 .NET 程式碼編譯成 WebAssembly。 AOT 編譯會導致執行時間效能提升,代價是較大的應用程式大小。 重新連結 .NET WebAssembly 執行時間會修剪未使用的執行時間程式碼,進而改善下載速度。 如需詳細資訊,請參閱 預先 (AOT) 編譯執行時間重新連結

保存預先呈現的狀態

Blazor 支援在預先呈現的頁面中保存狀態,如此一來,當應用程式完全載入時,就不需要重新建立狀態。 如需詳細資訊,請參閱Prerender 和 integrate ASP.NET Core Razor 元件

錯誤界限

錯誤界限提供方便的方法來處理 UI 層級上的例外狀況。 如需詳細資訊,請參閱處理 ASP.NET Core Blazor 應用程式中的錯誤

SVG 支援

<foreignObject> 支援元素元素在 SVG 中顯示任意 HTML。 如需詳細資訊,請參閱ASP.NET Core Razor 元件

Blazor Server Interop 中的 JS 位元組陣列傳輸支援

Blazor 支援優化的位元組陣列 JS Interop,可避免將位元組陣列編碼和解碼為 Base64。 如需詳細資訊,請參閱下列資源:

查詢字串增強功能

改善使用查詢字串的支援。 如需詳細資訊,請參閱ASP.NET Core Blazor 路由和導覽

系結以選取多個

系結支援使用元素進行 <input> 多重選項選取。 如需詳細資訊,請參閱下列資源:

前端 (<head>) 內容控制項

Razor 元件可以修改頁面的 HTML <head> 元素內容,包括設定頁面的標題 (元素) <title> ,以及修改中繼資料 (元素) <meta> 。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制 <head> 內容

產生Angular和React元件

從 Razor Web 架構的元件產生架構特定的 JavaScript 元件,例如Angular或React。 如需詳細資訊,請參閱ASP.NET Core Razor 元件

從 JavaScript 轉譯元件

針對現有的 JavaScript 應用程式,以動態方式從 JavaScript 轉 Razor 譯元件。 如需詳細資訊,請參閱ASP.NET Core Razor 元件

自訂元素

實驗性支援可用於建置使用標準 HTML 介面的自訂元素。 如需詳細資訊,請參閱ASP.NET Core Razor 元件

從上階元件推斷元件泛型型別

上階元件可以使用新的 [CascadingTypeParameter] 屬性,依名稱將類型參數串聯至子系。 如需詳細資訊,請參閱ASP.NET Core Razor 元件

動態轉譯的元件

使用新的內 DynamicComponent 建元件,依類型轉譯元件。 如需詳細資訊,請參閱動態轉譯 ASP.NET Core Razor 元件

改善 Blazor 的協助工具

使用新的 FocusOnNavigate 元件,在從一個頁面巡覽到另一個頁面之後,根據 CSS 選取器將 UI 焦點設定為元素。 如需詳細資訊,請參閱ASP.NET Core Blazor 路由和導覽

自訂事件引數支援

Blazor 支援自訂事件引數,可讓您使用自訂事件將任意資料傳遞至 .NET 事件處理常式。 如需詳細資訊,請參閱ASP.NET Core Blazor 事件處理

必要參數

套用新 [EditorRequired] 屬性以指定必要的元件參數。 如需詳細資訊,請參閱ASP.NET Core Razor 元件

搭配頁面、檢視和元件的 JavaScript 檔案組合

將頁面、檢視和 Razor 元件的 JavaScript 檔案共置為在應用程式中組織腳本的便利方式。 如需詳細資訊,請參閱ASP.NET Core Blazor JavaScript 互通性 (JS interop)

JavaScript 初始化運算式

JavaScript 初始化運算式會在應用程式載入前後 Blazor 執行邏輯。 如需詳細資訊,請參閱ASP.NET Core Blazor JavaScript 互通性 (JS interop)

串流 JavaScript Interop

Blazor 現在支援直接在 .NET 和 JavaScript 之間串流資料。 如需詳細資訊,請參閱下列資源:

泛型型別條件約束

現在支援泛型型別參數。 如需詳細資訊,請參閱ASP.NET Core Razor 元件

WebAssembly 部署配置

使用部署配置,在受限制的安全性環境中啟用 Blazor WebAssembly 應用程式下載。 如需詳細資訊,請參閱ASP.NET Core Blazor WebAssembly 應用程式的部署配置

新 Blazor 文章

除了 Blazor 上述各節所述的功能之外,下列主題也提供新的 Blazor 文章:

使用 .NET MAUI 、WPF 和 Windows Forms 建 Blazor Hybrid 置應用程式

使用 Blazor Hybrid 將桌面和行動原生用戶端架構與 .NET 和 Blazor 混合:

  • .NET Multi-platform App UI.NET MAUI () 是使用 C# 和 XAML 建立原生行動和傳統型應用程式的跨平臺架構。
  • Blazor Hybrid應用程式可以使用WINDOWS PRESENTATION FOUNDATION (WPF) 和Windows Forms架構來建置。

重要

Blazor Hybrid 處於預覽狀態,在最終發行之前不應在生產應用程式中使用。

如需詳細資訊,請參閱下列資源:

Kestrel

HTTP/3 目前處於草稿中,因此可能會變更。 ASP.NET Core中的 HTTP/3 支援未發行,它是 .NET 6 中包含的預覽功能。

Kestrel 現在支援 HTTP/3。 如需詳細資訊,請參閱搭配使用 HTTP/3 搭配 ASP.NET Core Kestrel Web 服務器,以及.NET 6 中的部落格文章 HTTP/3 支援

所選記錄的新 Kestrel 記錄類別

在此變更之前,啟用 的詳細資訊記錄 Kestrel 會非常昂貴,因為所有 Kestrel 共用 Microsoft.AspNetCore.Server.Kestrel 記錄類別名稱。 Microsoft.AspNetCore.Server.Kestrel 仍然可以使用,但下列新的子類別允許更多控制記錄:

  • Microsoft.AspNetCore.Server.Kestrel (目前類別) : ApplicationErrorConnectionHeadResponseBodyWriteRequestBodyNotEntirelyReadRequestBodyStartApplicationNeverCompletedRequestBodyDrainTimedOutResponseMinimumDataRateNotSatisfiedRequestBodyDoneInvalidResponseHeaderRemoved 、 。 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, HPackEncodingError, Http2FrameReceived, Http2FrameSending, Http2MaxConcurrentStreamsReached.
  • Microsoft.AspNetCore.Server.Kestrel.Http3: Http3ConnectionError, Http3ConnectionClosing, Http3ConnectionClosed, Http3StreamAbort, Http3FrameReceived, Http3FrameSending.

現有的規則可繼續運作,但您現在可以更選擇性地選擇啟用哪些規則。 例如,只針對不正確的要求啟用 Debug 記錄的可觀察性額外負荷會大幅減少,而且可以使用下列設定來啟用:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.Kestrel.BadRequests": "Debug"
    }
  }

記錄篩選會套用具有最長相符類別前置詞的規則。 如需詳細資訊,請參閱 如何套用篩選規則

透過 EventSource 事件發出 Kestrel ServerOptions

Kestrel EventSource會在啟用詳細資訊 EventLevel.LogAlways 時發出包含 ON 序列化 KestrelServerOptions 的新事件 JS 。 此事件可讓您更輕鬆地在分析收集的追蹤時推斷伺服器行為。 下列 JS ON 是事件承載的範例:

{
  "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"
    }
  ]
}

拒絕 HTTP 要求的新 DiagnosticSource 事件

Kestrel 現在會針對在伺服器層拒絕的 HTTP 要求發出新的 DiagnosticSource 事件。 在這項變更之前,無法觀察這些拒絕的要求。 新的 DiagnosticSource 事件 Microsoft.AspNetCore.Server.Kestrel.BadRequest 包含 , IBadRequestExceptionFeature 可用來對拒絕要求的原因進行簡介。

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();
}

如需詳細資訊,請參閱中的 Kestrel 記錄和診斷

從 Accept Socket 建立 ConnectionCoNtext

新的 SocketConnectionContextFactory 可讓您從接受的通訊端建立 ConnectionContext 。 這可讓您建置自訂通訊端型 IConnectionListenerFactory ,而不會遺失 SocketConnection中發生的所有效能工作和集區。

請參閱 自訂 IConnectionListenerFactory 的這個範例 ,其中顯示如何使用這個 SocketConnectionContextFactory

Kestrel是預設的啟動設定檔,Visual Studio

所有新 dotnet Web 專案的預設啟動設定檔為 Kestrel 。 開始 Kestrel 速度明顯更快,而且在開發應用程式時會產生更回應的體驗。

IIS Express仍可作為啟動設定檔,適用于Windows驗證或埠共用等案例。

的 Localhost 埠是隨機的 Kestrel

如需詳細資訊,請參閱本檔中的 Kestrel 範本產生的埠

驗證和授權

驗證服務器

.NET 3 至 .NET 5 使用Identity Server4作為範本的一部分,以支援發行 SPA 和 Blazor 應用程式的 JWT 權杖。 範本現在使用 Duende Identity 伺服器

如果您要擴充身分識別模型並更新現有的專案,您需要從 IdentityServer4.IdentityServerDuende.IdentityServer 更新程式碼中的命名空間,並遵循其 移轉指示

Duende Identity Server 的授權模型已變更為相互授權,在生產環境中使用時可能需要授權費用。 如需詳細資訊,請參閱 Duende 授權頁面

延遲的用戶端憑證交涉

開發人員現在可以在 上 HttpsConnectionAdapterOptions 指定ClientCertificateMode.DelayCertificate,選擇使用延遲用戶端憑證交涉。 這只適用于 HTTP/1.1 連線,因為 HTTP/2 禁止延遲憑證重新交涉。 此 API 的呼叫端必須先緩衝要求本文,才能要求用戶端憑證:

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 == true)
    {
        // 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();

Cookie 驗證滑動到期現在可以使用新的 OnCheckSlidingExpiration 自訂或隱藏。 例如,此事件可由需要定期 Ping 伺服器的單頁應用程式使用,而不會影響驗證會話。

其他

熱重載

使用熱重新載入,快速讓 UI 和程式碼更新為執行中的應用程式,而不會遺失應用程式狀態,以獲得更快速且更具生產力的開發人員體驗。 如需詳細資訊,請參閱.NET 熱重新載入 .NET熱重新載入 .NET 熱重新載入進度和更新 ASP.NET Core的支援,以及 Visual Studio 2022 重點

改善單頁應用程式 (SPA) 範本

ASP.NET Core專案範本已針對Angular和React更新,以針對更具彈性且更緊密地配合新式前端 Web 開發的常見模式的單頁應用程式使用改良模式。

先前,Angular和React的 ASP.NET Core範本會在開發期間使用特製化中介軟體,以啟動前端架構的開發伺服器,然後從 ASP.NET Core Proxy 要求到開發伺服器。 啟動前端開發伺服器的邏輯專屬於對應前端架構的命令列介面。 使用此模式支援其他前端架構,意謂著將額外的邏輯新增至 ASP.NET Core。

.NET 6 中Angular和React更新的 ASP.NET Core範本會四處翻轉此安排,並利用大多數新式前端架構的開發伺服器中的內建 Proxy 支援。 當啟動 ASP.NET Core應用程式時,前端開發伺服器就像之前一樣啟動,但開發伺服器會設定為 Proxy 要求至後端 ASP.NET Core進程。 設定 Proxy 的所有前端特定組態都是應用程式的一部分,而不是 ASP.NET Core。 設定要與其他前端架構搭配使用的 ASP.NET Core專案現在是直接的:使用在Angular和React範本中建立的模式,設定所選架構的前端開發伺服器,以 Proxy 到 ASP.NET Core後端。

ASP.NET Core應用程式的啟動程式碼不再需要任何單頁應用程式特定邏輯。 在開發期間啟動前端開發伺服器的邏輯會由新的 Microsoft.AspNetCore.SpaProxy 套件在執行時間插入應用程式。 後援路由是使用端點路由來處理,而不是使用 SPA 特定的中介軟體。

遵循此模式的範本仍然可以以單一專案的形式執行,Visual Studio或使用 dotnet run 命令列。 發佈應用程式時,ClientApp資料夾中的前端程式碼會建置並收集為先前的主機根目錄,ASP.NET Core應用程式並做為靜態檔案。 範本中包含的腳本會設定前端開發伺服器,以使用 ASP.NET Core 開發憑證使用 HTTPS。

.NET 6 中的草稿 HTTP/3 支援

HTTP/3 目前處於草稿中,因此可能會變更。 ASP.NET Core中的 HTTP/3 支援未發行,它是 .NET 6 中包含的預覽功能。

請參閱 .NET 6 中的部落格文章 HTTP/3 支援

可為 Null 的參考型別注釋

ASP.NET Core 6.0 原始程式碼的部分已套用可為 Null 的注釋

藉由在C# 8 中使用新的可為 Null 功能,ASP.NET Core可以在處理參考類型時提供額外的編譯時間安全性。 例如,防止 null 參考例外狀況。 選擇使用可為 Null 注釋的專案可能會看到來自 ASP.NET Core API 的新建置時間警告。

若要啟用可為 Null 的參考型別,請將下列屬性新增至專案檔:

<PropertyGroup>
    <Nullable>enable</Nullable>
</PropertyGroup>

如需詳細資訊,請參閱 可為 Null 的參考型別

來源Code Analysis

已新增數個 .NET 編譯器平臺分析器,以檢查應用程式程式碼是否有不正確的中介軟體設定或順序、路由衝突等問題。如需詳細資訊,請參閱ASP.NET Core 應用程式中的程式碼分析

Web 應用程式範本改善

Web 應用程式範本:

  • 使用新的 最小裝載模型
  • 大幅減少建立應用程式所需的檔案和程式程式碼數目。 例如,ASP.NET Core空白 Web 應用程式會建立一個 C# 檔案,其中包含四行程式碼,而且是完整的應用程式。
  • Startup.cs將 和 Program.cs 整合至單 Program.cs 一檔案。
  • 使用 最上層語句 ,將應用程式所需的程式碼降到最低。
  • 使用全域 using 指示詞來消除或最小化所需的語句行數using

範本產生的埠 Kestrel

隨機埠會在專案建立期間指派,以供網頁伺服器使用 Kestrel 。 隨機埠有助於在相同電腦上執行多個專案時,將埠衝突降至最低。

建立專案時,產生的 Properties/launchSettings.json 檔案中會指定介於 5000-5300 之間的隨機 HTTP 埠和介於 7000-7300 之間的隨機 HTTPS 埠。 您可以在 檔案中 Properties/launchSettings.json 變更埠。 如果未指定埠, Kestrel 預設為 HTTP 5000 和 HTTPS 5001 埠。 如需詳細資訊,請參閱設定 ASP.NET Core Kestrel Web 服務器的端點

新的記錄預設值

已對 appsettings.jsonappsettings.Development.json 進行下列變更:

- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

"Microsoft": "Warning" 變更為 "Microsoft.AspNetCore": "Warning" 會導致記錄命名空間中所有參考訊息 Microsoft,但除外Microsoft.AspNetCore 。 例如, Microsoft.EntityFrameworkCore 現在會記錄在資訊層級。

自動新增開發人員例外狀況頁面中介軟體

清除環境中DeveloperExceptionPageMiddleware 預設會新增 。 不再需要將下列程式碼新增至 Web UI 應用程式:

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

支援 HttpSysServer 中的 Latin1 編碼要求標頭

HttpSysServer現在支援解碼要求標頭, Latin1 方法是將 上的 屬性 HttpSysOptions 設定 UseLatin1RequestHeaderstrue 來編碼:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys(o => o.UseLatin1RequestHeaders = true);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

ASP.NET Core模組記錄包含時間戳記和 PID

ASP.NET CORE模組 (適用于 IIS (ANCM) 增強型診斷記錄的 ANCM) ,包括發出記錄之進程的時間戳記和PID。 記錄時間戳記和 PID 可讓您在多個 IIS 背景工作進程執行時,更輕鬆地診斷 IIS 中重迭進程重新開機的問題。

產生的記錄現在類似于範例輸出,如下所示:

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

可設定 IIS 的未連接內送緩衝區大小

IIS 伺服器先前只會緩衝 64 KiB 的未受限制要求主體。 64 KiB 緩衝會導致讀取受限於該大小上限,這會影響具有大型傳入主體的效能,例如上傳。 在 .NET 6 中,預設緩衝區大小會從 64 KiB 變更為 1 MiB,這應該可改善大型上傳的輸送量。 在我們的測試中,700 MiB 上傳,用來花費 9 秒,現在只需要 2.5 秒。

當應用程式無法快速從要求本文讀取時,較大的緩衝區大小缺點是增加每個要求記憶體耗用量。 因此,除了變更預設緩衝區大小之外,可設定緩衝區大小,允許應用程式根據工作負載設定緩衝區大小。

檢視元件標籤協助程式

請考慮具有選擇性參數的檢視元件,如下列程式碼所示:

class MyViewComponent
{
    IViewComponentResult Invoke(bool showSomething = false) { ... }
}

使用 ASP.NET Core 6 時,可以叫用標籤協助程式,而不需要指定 showSomething 參數的值:

<vc:my />

Angular範本已更新為 Angular 12

Angular的 ASP.NET Core 6.0 範本現在使用Angular 12

React範本已更新為React 17

Json.NET 輸出格式器寫入磁片之前,可設定的緩衝區臨界值

注意:建議您使用輸出格式器, System.Text.Json 除非 Newtonsoft.Json 因為相容性原因而需要序列化程式。 System.Text.Json序列化程式是完全 async 且有效率地適用于較大的承載。

根據預設, Newtonsoft.Json 輸出格式器會先在記憶體中回應最多 32 KiB,再緩衝至磁片。 這是為了避免執行同步 IO,這可能會導致其他副作用,例如執行緒耗盡和應用程式死結。 不過,如果回應大於 32 KiB,就會發生相當多的磁片 I/O。 記憶體閾值現在可透過 MvcNewtonsoftJsonOptions.OutputFormatterMemoryBufferThreshold 屬性設定,再緩衝至磁片:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages()
            .AddNewtonsoftJson(options =>
            { 
                options.OutputFormatterMemoryBufferThreshold = 48 * 1024;
            });

var app = builder.Build();

如需詳細資訊,請參閱此GitHub提取要求NewtonsoftJsonOutputFormatterTest.cs檔案。

更快速地取得和設定 HTTP 標頭

已新增新的 API,以公開 上 Microsoft.Net.Http.Headers.HeaderNames 可用的所有通用標頭做為 屬性, IHeaderDictionary 以方便使用 API。 例如,下列程式碼中的內嵌中介軟體會使用新的 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();

針對實作的標頭,get 和 set 存取子會直接移至欄位並略過查閱來實作。 對於未實作的標頭,存取子可以略過對實作標頭的初始查閱,並直接執行 Dictionary<string, StringValues> 查閱。 避免查閱會導致這兩種案例的存取速度更快。

非同步串流

ASP.NET Core現在支援從控制器動作和來自 的 JS 回應進行非同步串流ON 格式器。 從動作傳 IAsyncEnumerable 回 時,不會再緩衝記憶體中的回應內容再傳送。 傳回可非同步列舉的大型資料集時,不緩衝有助於減少記憶體使用量。

請注意,Entity Framework Core 提供 用於查詢資料庫的 實 IAsyncEnumerable 作。 .NET 6 中 ASP.NET Core的改善支援 IAsyncEnumerable 可讓 EF Core 搭配 ASP.NET Core更有效率。 例如,下列程式碼在傳送回應之前,不會再將產品資料緩衝處理到記憶體中:

public IActionResult GetMovies()
{
    return Ok(_context.Movie);
}

不過,在 EF Core 中使用延遲載入時,這個新行為可能會導致在列舉資料時發生並行查詢執行所造成的錯誤。 應用程式可以藉由緩衝資料還原回先前的行為:

public async Task<IActionResult> GetMovies2()
{
    return Ok(await _context.Movie.ToListAsync());
}

如需有關此行為變更的其他詳細資料,請參閱相關 公告

HTTP 記錄中介軟體

HTTP 記錄是新的內建中介軟體,可記錄 HTTP 要求和 HTTP 回應的相關資訊,包括標頭和整個本文:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();
app.UseHttpLogging();

app.MapGet("/", () => "Hello World!");

app.Run();

使用先前的程式碼記錄資訊流覽至 / ,類似于下列輸出:

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

上述輸出已啟用下列 appsettings.Development.json 檔案:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
    }
  }
}

HTTP 記錄提供下列專案的記錄:

  • HTTP 要求資訊
  • 通用屬性
  • 標題
  • body
  • HTTP 回應資訊

若要設定 HTTP 記錄中介軟體,請指定 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

IConnectionSocketFeature要求功能可讓您存取與目前要求相關聯的基礎接受通訊端。 它可透過 FeatureCollection 上的 HttpContext 存取。

例如,下列應用程式會在 LingerState 接受的通訊端上設定 屬性:

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();

中的泛型型別條件約束 Razor

在使用 @typeparam 指示詞中 Razor 定義泛型型別參數時,現在可以使用標準 C# 語法來指定泛型型別條件約束:

較小的 SignalR 、 Blazor Server 和 MessagePack 腳本

SignalR、MessagePack 和 Blazor Server 腳本現在明顯較小、啟用較小的下載、瀏覽器的 JavaScript 剖析和編譯較少,以及更快的啟動速度。 大小縮減:

  • signalr.js: 70%
  • blazor.server.js: 45%

較小的腳本是 Ben Adams社群貢獻的結果。 如需縮小大小詳細資料的詳細資訊,請參閱Ben 的GitHub提取要求

啟用 Redis 分析會話

Gabriel Lucaci的社群貢獻可透過Microsoft.Extensions.Cacheing.StackExchangeRedis啟用 Redis 分析會話:

using StackExchange.Redis.Profiling;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.ProfilingSession = () => new ProfilingSession();
});

如需詳細資訊,請參閱 StackExchange.Redis 分析

IIS 中的陰影複製

實驗性功能已新增至ASP.NET Core模組 (ANCM) ,讓 IIS新增陰影複製應用程式元件的支援。 目前 .NET 會在應用程式執行時鎖定應用程式二進位檔,Windows讓無法在應用程式執行時取代二進位檔。 雖然我們的建議仍使用 應用程式離線檔案,但我們辨識某些案例 (例如 FTP 部署,) 無法這麼做。

在這種情況下,藉由自訂 ASP.NET Core模組處理常式設定來啟用陰影複製。 在大部分情況下,ASP.NET Core應用程式未 web.config 簽入您可以修改的原始檔控制。 在 ASP.NET Core 中, web.config 通常是由 SDK 產生。 下列範例 web.config 可用來開始使用:

<?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>

IIS 中的陰影複製是一項實驗性功能,不保證是 ASP.NET Core的一部分。 請在此GitHub問題中留下 IIS 陰影複製的意見反應。

其他資源