相关文章推荐
长情的椅子  ·  ASP.NET SignalR 中心 ...·  1 周前    · 
文武双全的刺猬  ·  error: Raw AIDL ...·  7 月前    · 

ASP.NET Core MVC 和 Razor 改善

最小 API

基本 API 的架構是建立具有最低相依性的 HTTP API。 它們非常適合想要只包含核心 ASP.NET 中最小檔案、功能和相依性的微服務和應用程式。 如需詳細資訊,請參閱

  • 教學課程:使用 ASP.NET Core 建立最小 API
  • 最小 API 與具有控制器的 API 之間的差異
  • 基本 API 快速參考
  • 程式碼範例已移轉至 6.0 中新的最小裝載模型
  • SignalR

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

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

    SignalR 效能改善

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

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

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

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

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

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

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

    ASP.NET 核心效能和 API 改善

    已進行許多變更,以減少配置並改善整個堆疊的效能:

  • 非配置 應用程式。使用 擴充方法。 的新多載需要傳遞內容, next 以儲存使用其他多載 app.Use 時所需的兩個內部個別要求配置。
  • 存取 時 HttpRequest.Cookies 減少記憶體配置。 如需詳細資訊,請參閱 這個 GitHub 問題。
  • 針對 Windows HTTP.sys Web 服務器 使用 LoggerMessage.Define 。 擴充 ILogger 方法呼叫已取代為 對 LoggerMessage.Define 的呼叫。
  • 將 Socket連線ion 中的 每個連線額外負荷減少 ~30%。 如需詳細資訊,請參閱 此 GitHub 提取要求
  • 藉由移除泛型型別中的記錄委派來減少配置。 如需詳細資訊,請參閱 此 GitHub 提取要求
  • 更快速的 GET 存取權(約 50%)存取常用的功能,例如 IHttpRequestFeature IHttpResponseFeature IHttpResponseBodyFeature IRouteValuesFeature IEndpointFeature 。 如需詳細資訊,請參閱 此 GitHub 提取要求
  • 針對已知的標頭名稱使用單一實例字串,即使它們不在保留的標頭區塊中也一樣。 使用單一實例字串有助於防止長時間連線中相同字串的多個重複專案,例如 , 在 中 Microsoft.AspNetCore.WebSockets 。 如需詳細資訊,請參閱 這個 GitHub 問題。
  • 在 中 Kestrel 重複使用 HttpProtocol CancellationTokenSource 。 使用 上的 CancellationTokenSource CancellationTokenSource.TryReset 方法,在尚未取消權杖時重複使用權杖。 如需詳細資訊,請參閱 此 GitHub 問題和 這段 影片
  • 在要求 Cookie 集合 Microsoft.AspNetCore.Http 實作及使用 AdaptiveCapacityDictionary ,以更有效率地存取字典。 如需詳細資訊,請參閱 此 GitHub 提取要求
  • 降低閒置 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 個位元組,而是只為每個配置 350 個位元組 IOQueue 。 每個佇列會進行配置以避免爭用。 具有 5000 個閒置連線的 WebSocket 伺服器從配置 ~1.75 MB(350 位元組 * 5000)到設定物件 ~2.8 kb(350 位元組 * 8)。 SocketSender

    使用 SslStream 讀取零個位元組

    無緩衝讀取是在 ASP.NET Core 中使用的技術,可在通訊端上沒有可用的資料時,避免從記憶體集區租用記憶體。 在此變更之前,具有 5000 個閒置連線的 WebSocket 伺服器需要 ~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 ,而內部類型會 Stream 調整為 PipeReader 。 在 中 Kestrel , StreamPipeReader 用來將 基礎 SslStream 調整為 PipeReader 。 因此,必須在 上 PipeReader 公開這些零位元組讀取語意。

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

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

    從 移除板 SlabMemoryPool

    為了減少堆積的片段,採用一種技術, Kestrel 其中它會在其記憶體集區中配置 128 KB 的記憶板。 然後,板塊進一步分成 4 KB 區塊,供 Kestrel 內部使用。 板必須大於 85 KB,才能強制配置大型物件堆積,以嘗試防止 GC 重新放置此陣列。 不過,隨著新 GC 世代的推出, Pinned Object Heap (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 應用程式進行數個專案範本變更,包括針對先前 Blazor Server 應用程式在檔案中顯示的 _Host.cshtml 版面配置內容使用 Pages/_Layout.cshtml 檔案。 從 6.0 專案範本建立應用程式,或存取專案範本的 ASP.NET Core 參考來源,以研究變更:

  • Blazor Server
  • Blazor WebAssembly
  • Blazor WebAssembly 原生相依性支援

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

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

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

    保存預先呈現的狀態

    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 中的 .NET 方法呼叫 JavaScript 函式
  • 從 ASP.NET Core Blazor 中的 .NET 方法呼叫 JavaScript 函式
  • 查詢字串增強功能

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

    系結以選取多個

    系結支援具有元素的 <input> 多個選項選取專案。 如需詳細資訊,請參閱以下資源:

  • ASP.NET 核心 Blazor 資料系結
  • ASP.NET 核心 Blazor 表單和輸入元件
  • 前端 ( <head> ) 內容控制項

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

    產生 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 核心 Razor 元件

    改善 Blazor 的協助工具

    使用新的 FocusOnNavigate 元件,在從某個頁面巡覽至另一個頁面之後,根據 CSS 選取器,將 UI 焦點設定為元素。 如需詳細資訊,請參閱 ASP.NET 核心 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 之間串流資料。 如需詳細資訊,請參閱以下資源:

  • 從 .NET 串流至 JavaScript
  • 從 JavaScript 串流至 .NET
  • 泛型型別條件約束

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

    WebAssembly 部署配置

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

    新 Blazor 文章

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

  • ASP.NET 核心 Blazor 檔案下載 :瞭解如何使用原生 byte[] 串流 Interop 下載檔案,以確保有效率地傳輸至用戶端。
  • 使用 ASP.NET Core Blazor 中的影像:探索如何在應用程式中處理影像 Blazor ,包括如何串流影像資料和預覽影像。
  • 使用 、WPF 和 Windows Forms 建 Blazor Hybrid 置 .NET MAUI 應用程式

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

  • .NET Multi-platform App UI ( .NET MAUI ) 是使用 C# 和 XAML 建立原生行動和傳統型應用程式的跨平臺架構。
  • Blazor Hybrid 應用程式可以使用 Windows Presentation Foundation (WPF) 和 Windows Forms 架構來建置。
  • Blazor Hybrid 處於預覽狀態,在最終版本之前不應該在生產應用程式中使用。

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

  • Preview ASP.NET Core Blazor Hybrid 檔
  • 什麼是 .NET MAUI ?
  • Microsoft .NET 部落格 (類別: 「 .NET MAUI 」)
  • 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(目前類別): ApplicationErrorConnectionHeadResponseBodyWrite 、、 ApplicationNeverCompletedRequestBodyDoneRequestBodyDrainTimedOutRequestBodyNotEntirelyReadResponseMinimumDataRateNotSatisfiedRequestBodyStart 、、 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, 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 建立 連線ionCoNtext

    新的 SocketConnectionContextFactory 可讓您從接受的通訊端建立 ConnectionContext 。 這可讓您建置以通訊端為基礎的 IConnectionListenerFactory 自訂通訊端,而不會遺失通訊端的所有效能工作和集區發生 于 Socket連線ion 中。

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

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

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

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

    的 Localhost 埠是隨機的 Kestrel

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

    驗證和授權

    驗證服務器

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

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

    Duende Identity 伺服器的授權模型已變更為相互授權,在生產環境中使用時可能需要授權費用。 如需詳細資訊,請參閱 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)
            // 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 熱重新載入 ASP.NET Core .NET 熱重新載入進度更新的支援和 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。 現在,使用 Angular 和 React 範本中建立的模式,設定 ASP.NET Core 專案以與其他前端架構搭配運作:為所選架構設定前端開發伺服器,以 Proxy 至 ASP.NET Core 後端。

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

    遵循此模式的範本仍然可以在 Visual Studio 中以單一專案的形式執行,或是從命令列使用 dotnet run 。 發佈應用程式時,ClientApp 資料夾中的 前端程式碼會建置並收集到主機的 Web 根目錄 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 的參考型別

    原始程式碼分析

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

    Web 應用程式範本改善

    Web 應用程式範本:

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

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

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

    新的記錄預設值

    對 和 appsettings.Development.json 進行了 appsettings.json 下列變更:

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

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

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

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

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

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

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

    var builder = WebApplication.CreateBuilder(args);
    builder.WebHost.UseHttpSys(o => o.UseLatin1RequestHeaders = true);
    var app = builder.Build();
    app.MapGet("/", () => "Hello World!");
    app.Run();
    

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

    IIS (ANCM) 增強型診斷記錄 ASP.NET 核心模組 (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,這應該可改善大型上傳的輸送量。 在我們的測試中,過去花費 9 秒的 700 MiB 上傳現在只需要 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 現在支援來自控制器動作的非同步串流,以及 ON 格式子的 JS 回應。 從動作傳 IAsyncEnumerable 回 時,在傳送回應內容之前,不會再緩衝記憶體中的回應內容。 傳回可以非同步列舉的大型資料集時,不緩衝有助於減少記憶體使用量。

    請注意,Entity Framework Core 提供 的實作 IAsyncEnumerable 來查詢資料庫。 改善 .NET 6 中 ASP.NET Core 的支援 IAsyncEnumerable ,可讓搭配 ASP.NET Core 更有效率地使用 EF 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 要求資訊
  • 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();
    

    I連線ionSocketFeature

    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 的 GitHub 提取要求

    啟用 Redis 分析會話

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

    using StackExchange.Redis.Profiling;
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddStackExchangeRedisCache(options =>
        options.ProfilingSession = () => new ProfilingSession();
    

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

    IIS 中的陰影複製

    實驗性功能已新增至 適用于 IIS 的 ASP.NET 核心模組 (ANCM),以新增陰影複製應用程式元件的 支援 。 目前 .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 陰影複製的意見反應。

  • 程式碼範例已移轉至 6.0 中新的最小裝載模型
  • .NET 6 的新功能
  •