...

.NET 6 Preview 5 中的(de) ASP.NET Core 更新

2021-06-29

rt.NET 6 Preview 5 中的(de) ASP.NET Core 更新

.NET 6 Preview 5 現已推出(chū),其中包括對 ASP.NET Core 的(de)許多重大(dà)改進。

以(yǐ)下是(shì)此預覽版中的(de)新功能:

  • .NET 熱重載更新 dotnet watch
  • ASP.NET Core SPA 模闆更新到(dào) Angular 11 和(hé / huò) React 17
  • 在(zài) SVG foreignObject元素中使用 Razor 語法
  • 爲(wéi / wèi) Action和(hé / huò) RenderFragment組件參數指定 null
  • 通過運行時(shí)重鏈接減少 Blazor WebAssembly 下載大(dà)小
  • 在(zài) Json.NET 輸出(chū)格式化程序中寫入磁盤之(zhī)前可配置的(de)緩沖區阈值
  • 用于(yú)更好地(dì / de)過濾 Kestrel 日志的(de)子(zǐ)類别
  • 更快地(dì / de)獲取和(hé / huò)設置 HTTP 标頭
  • IIS 的(de)可配置未消費的(de)傳入緩沖區大(dà)小

開始

要(yào / yāo)在(zài) .NET 6 Preview 5 中開始使用 ASP.NET Core,請安裝 .NET 6 SDK。

如果你在(zài) Windows 上(shàng)使用 Visual Studio,我們建議安裝 Visual Studio 2019 16.11 的(de)最新預覽版。Visual Studio 2022 Preview 1也(yě)在(zài)今天發布,.NET 6 Preview 5 包含在(zài)該版本中。如果您使用的(de)是(shì) macOS,我們建議您安裝 Visual Studio 2019 for Mac 8.10 的(de)最新預覽版。

要(yào / yāo)使用 .NET MAUI 和(hé / huò) Blazor 設置跨平台原生應用程序,請參閱.NET MAUI 入門指南 中的(de)最新說(shuō)明。請務必查看宣布 .NET MAUI 預覽 5 的(de)博客文章,了(le/liǎo)解有關此版本中 .NET MAUI 新增功能的(de)所有詳細信息。

注意:Visual Studio 2022 預覽版 1 尚不(bù)支持 .NET MAUI。對于(yú) .NET MAUI 開發,請改用 Visual Studio 2019 16.11 的(de)最新預覽版。

要(yào / yāo)安裝用于(yú)提前 (AOT) 編譯和(hé / huò)運行時(shí)重新鏈接的(de)最新 .NET WebAssembly 工具,請從提升的(de)命令提示符運行以(yǐ)下命令:

dotnet workload install microsoft-net-sdk-blazorwebassembly-aot

如果您之(zhī)前安裝了(le/liǎo) .NET WebAssembly 工作負載,您可以(yǐ)通過從提升的(de)命令提示符運行以(yǐ)下命令将其更新到(dào) .NET 6 Preview 5:

dotnet workload update

注意:使用 Visual Studio 2022 Preview 1 附帶的(de) .NET 6 Preview 5 SDK 安裝可選 SDK 工作負載存在(zài)一(yī / yì /yí)個(gè)已知問題。要(yào / yāo)解決此問題,請從 https://dot.net/ 安裝 .NET 6 Preview 5 SDK安裝 Visual Studio 2022 預覽版 1 後的(de) get-dotnet6。

升級現有項目

要(yào / yāo)将現有的(de) ASP.NET Core 應用程序從 .NET 6 Preview 4 升級到(dào) .NET 6 Preview 5:

  • 将所有 Microsoft.AspNetCore.* 包引用更新爲(wéi / wèi).6.0.0-preview.5.*
  • 将所有 Microsoft.Extensions.* 包引用更新爲(wéi / wèi).6.0.0-preview.5.*

要(yào / yāo)将 .NET MAUI Blazor 應用從 .NET 6 Preview 4 升級到(dào) .NET 6 Preview 5,我們建議從使用 .NET 6 Preview 5 SDK 創建的(de)新 .NET MAUI Blazor 項目開始,然後從原始項目複制代碼。

查看 .NET 6 的(de) ASP.NET Core 重大(dà)變更的(de)完整列表。

.NET 熱重載更新 dotnet watch

我們一(yī / yì /yí)直緻力于(yú)對 .NET 6 的(de) .NET Hot Reload 進行各種改進。其中一(yī / yì /yí)些改進在(zài) .NET 6 Preview 5 中可用,而(ér)其他(tā)改進仍在(zài)進行中,将在(zài)未來(lái)的(de)預覽更新中完善。

您不(bù)再需要(yào / yāo)在(zài) launchSettings.json 中指定hotReloadProfile 以(yǐ)使用dotnet watch 來(lái)啓用 .NET Hot Reload . 能夠支持熱重載的(de)項目現在(zài)會默認啓用 .NET 熱重載。

當進行了(le/liǎo)無法熱重載的(de)代碼編輯(“粗魯”編輯)時(shí),dotnet watch現在(zài)将詢問您是(shì)否要(yào / yāo)重新啓動應用程序以(yǐ)應用更改:

watch : Unable to apply hot reload because of a rude edit. Rebuilding the app...
watch : Unable to handle changes to C:\Users\daroth\Desktop\BlazorApp\Pages\Index.razor.
watch : Do you want to restart your app - Yes (y) / No (n) / Always (a) / Never (v)?

這(zhè)些選項具有以(yǐ)下行爲(wéi / wèi):

  • 選擇 是(shì) 将重新啓動應用程序。
  • 選擇  不(bù)會重新啓動應用程序,并且會保持應用程序運行而(ér)不(bù)應用更改。
  • 當無法熱重新加載更改時(shí),選擇“*始終”*将根據需要(yào / yāo)重新啓動應用程序。
  • 選擇 從不(bù) 不(bù)會重新啓動應用程序并避免将來(lái)出(chū)現提示。

您始終可以(yǐ)使用 Ctrl+R 手動重新啓動應用程序。

注意:此版本中存在(zài)一(yī / yì /yí)個(gè)已知問題,即選擇“*始終”*仍會繼續提示将來(lái)進行粗魯編輯。這(zhè)将在(zài)未來(lái)的(de)預覽版本中得到(dào)解決。

要(yào / yāo)在(zài)使用時(shí)禁用對 .NET Hot Reload 的(de)支持dotnet watch,請使用命令行選項。--no-hot-reload

使用 dotnet watch 進行 .NET Hot Reload 現在(zài)也(yě)将正确檢測 Blazor WebAssembly 應用程序中的(de)“粗魯”編輯。當刷新浏覽器或在(zài)單獨的(de)浏覽器 Tab 或浏覽器實例中加載應用程序時(shí),應用于(yú) Blazor WebAssembly 應用程序的(de)更改将重新應用于(yú)應用程序。

ASP.NET Core SPA 模闆更新到(dào) Angular 11 和(hé / huò) React 17

用于(yú) Angular 和(hé / huò) React 的(de) ASP.NET Core 單頁應用 (SPA) 模闆已更新爲(wéi / wèi) Angular 11 和(hé / huò) React 17。我們還希望在(zài)未來(lái)的(de) .NET 6 預覽版中将 Angular 模闆進一(yī / yì /yí)步更新爲(wéi / wèi) Angular 12,因爲(wéi / wèi) Angular 12 已經正式發布了(le/liǎo)。

在(zài) SVG foreignObject元素中支持 Razor 語法

您現在(zài)可以(yǐ)在(zài) SVGforeignObject元素中使用 Razor 語法,包括使用 Blazor 組件:

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
   <rect x="0" y="0" rx="10" ry="10" width="200" height="200" stroke="black" fill="none" />
   <foreignObject x="20" y="20" width="160" height="160">
       <p>@message</p>
   </foreignObject>
</svg>

@code {
   string message = "Wow, it's so nice that this text wraps like it's HTML...because that's what it is!";
}

我們還進行了(le/liǎo)大(dà)量驗證和(hé / huò)測試,以(yǐ)确保 Blazor 對 SVG 場景有良好的(de)支持。我們認爲(wéi / wèi) Blazor 的(de) SVG 支持現在(zài)處于(yú)良好狀态。如果您在(zài)此版本的(de) Blazor 中使用 SVG 遇到(dào)任何問題,請通過在(zài)GitHub 上(shàng)創建 Issue 告訴我們。

爲(wéi / wèi)Action和(hé / huò)RenderFragment組件參數指定 null

現在(zài),您可以(yǐ)指定Blazor組件參數值Action和(hé / huò)RenderFragment爲(wéi / wèi) null,從而(ér)簡化采取可選的(de)回調參數或模闆參數的(de)新組件。

通過運行時(shí)重鏈接減少 Blazor WebAssembly 下載大(dà)小

默認 Blazor WebAssembly 應用程序的(de)最大(dà)部分之(zhī)一(yī / yì /yí)是(shì)該應用程序依賴的(de)基于(yú) WebAssembly 的(de) .NET 運行時(shí) ( dotnet.wasm )。Blazor WebAssembly 已經支持從 .NET 核心框架庫中修剪未使用的(de)代碼。但是(shì)運行時(shí)的(de)下載大(dà)小一(yī / yì /yí)直是(shì)固定的(de)。

并非每個(gè)應用程序都需要(yào / yāo)所有運行時(shí)邏輯。例如,很大(dà)一(yī / yì /yí)部分運行時(shí)邏輯和(hé / huò)相關數據文件是(shì)針對全球化場景的(de)。這(zhè)種全球化支持使 Blazor WebAssembly 應用程序能夠根據當前文化處理字符串、數字、日期等。但是(shì)對于(yú)不(bù)需要(yào / yāo)此功能的(de)應用程序,這(zhè)些數據和(hé / huò)邏輯都隻是(shì)多餘的(de)。

不(bù)需要(yào / yāo)全球化功能的(de) .NET 應用程序可以(yǐ)選擇不(bù)要(yào / yāo)它,通過在(zài)其項目文件中設置InvariantGlobalization屬性爲(wéi / wèi)true來(lái)使用不(bù)變的(de)全球化。在(zài) .NET 5 中,這(zhè)将允許 Blazor WebAssembly 應用程序避免下載全球化數據,但仍會包含 .NET 運行時(shí)中的(de)相關邏輯。

在(zài) .NET 6 Preview 5 中,您現在(zài)可以(yǐ)使用 .NET WebAssembly 工具(與用于(yú) .NET WebAssembly AOT 編譯的(de)工具相同)重新鏈接運行時(shí)以(yǐ)删除不(bù)需要(yào / yāo)的(de)邏輯并顯着減小運行時(shí)的(de)大(dà)小。如果您安裝了(le/liǎo) .NET WebAssembly 工作負載,則在(zài)您發布應用程序時(shí)會自動完成運行時(shí)重新鏈接。使用不(bù)變全球化模式時(shí),大(dà)小減少尤其顯着。

如果您還沒有安裝 .NET WebAssembly 工具,可以(yǐ)通過從管理員模式的(de)命令提示符運行以(yǐ)下命令來(lái)安裝:

dotnet workload install microsoft-net-sdk-blazorwebassembly-aot

下表顯示了(le/liǎo)使用 .NET 5 和(hé / huò) .NET 6 的(de)默認 Blazor WebAssembly 項目的(de)dotnet.wasm傳輸大(dà)小:

dotnet.wasm傳輸大(dà)小 (kB)
.NET 5 默認884
.NET 6 默認780
.NET 6 重新鏈接756
.NET 6 不(bù)變模式393

在(zài) Json.NET 輸出(chū)格式化程序中寫入磁盤之(zhī)前可配置的(de)緩沖區阈值

默認情況下,Newtonsoft.Json 輸出(chū)格式化程序(output formatter)在(zài)緩沖到(dào)磁盤之(zhī)前在(zài)内存中緩沖高達 32 KiB 的(de)響應。這(zhè)是(shì)爲(wéi / wèi)了(le/liǎo)避免執行同步 IO,但是(shì)這(zhè)會導緻其他(tā)副作用,例如線程饑餓和(hé / huò)應用程序死鎖。但是(shì),如果您的(de)響應大(dà)于(yú) 32 KiB,則會導緻大(dà)量可避免的(de)磁盤 I/O。您現在(zài)可以(yǐ)在(zài)緩沖到(dào)磁盤之(zhī)前配置内存阈值。

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages()
            .AddNewtonsoftJson(options =>
            {
                options.OutputFormatterMemoryBufferThreshold = 48 * 1024;
            });
}

注意:我們仍然建議使用 System.Text.Json output formatter,除非出(chū)于(yú)兼容性原因需要(yào / yāo) Newtonsoft.Json 序列化程序。System.Text.Json 序列化程序是(shì)完全異步的(de),将有效地(dì / de)适用于(yú)任何大(dà)小的(de)有效載荷。

用于(yú)更好地(dì / de)過濾 Kestrel 日志的(de)子(zǐ)類别

在(zài)此更改之(zhī)前,爲(wéi / wèi) Kestrel 啓用詳細日志記錄非常昂貴,因爲(wéi / wèi)所有 Kestrel 共享相同的(de)日志記錄類别名稱 (Microsoft.AspNetCore.Server.Kestrel )。我們現在(zài)将該類别拆分爲(wéi / wèi)多個(gè)新的(de)子(zǐ)類别:

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

雖然您現有的(de)規則将繼續有效(日志過濾應用具有最長匹配類别前綴的(de)規則),但您現在(zài)可以(yǐ)更有選擇性地(dì / de)選擇啓用哪些規則。例如,使用 Debug爲(wéi / wèi) bad requests 啓用日志記錄的(de)可觀察性開銷大(dà)大(dà)降低,可以(yǐ)通過以(yǐ)下配置實現:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.Kestrel.BadRequests""Debug"
    }
  }
}

更快地(dì / de)獲取和(hé / huò)設置 HTTP 頭

我們添加了(le/liǎo)新的(de) API 以(yǐ)将 System.Net.Http.HeaderNames 所有可用的(de)通用标頭公開爲(wéi / wèi)屬性,從而(ér)使 Microsoft.AspNetCore.Http.IHeaderDictionary API 更易于(yú)使用。例如,下面的(de)内聯中間件使用新 API 獲取/設置請求和(hé / huò)響應标頭:

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-preview5";
    await next.Invoke(context);
    var dateHeader = context.Response.Headers.Date;
    app.Logger.LogInformation("Response date: {date}", dateHeader);
});

對于(yú)已實現的(de)标頭,get/set訪問器是(shì)通過直接轉到(dào)字段并繞過查找來(lái)實現的(de)。對于(yú)未實現的(de)标頭,訪問者可以(yǐ)繞過針對已實現标頭的(de)初始查找并直接執行查找 Dictionary。這(zhè)導緻兩種情況下的(de)訪問速度更快。

方法分支類型平均操作/秒Delta
GetHeaders預覽4純文本25.793 納秒38,770,569.6——
GetHeaders預覽5純文本12.775 納秒78,279,480.0+101.9%
GetHeaders預覽4常見的(de)121.355 納秒8,240,299.3——
GetHeaders預覽5常見的(de)37.598 納秒26,597,474.6+222.8%
GetHeaders預覽4未知366.456 納秒2,728,840.7——
GetHeaders預覽5未知223.472 納秒4,474,824.0+64.0%






SetHeaders預覽4純文本49.324 納秒20,273,931.8——
SetHeaders預覽5純文本34.996 納秒28,574,778.8+40.9%
SetHeaders預覽4常見的(de)635.060 納秒1,574,654.3——
SetHeaders預覽5常見的(de)108.041 納秒9,255,723.7+487.7%
SetHeaders預覽4未知1,439.945 納秒694,470.8——
SetHeaders預覽5未知517.067 納秒1,933,985.7+178.4%

IIS 的(de)可配置未消耗傳入緩沖區大(dà)小

在(zài)此更改之(zhī)前,IIS 服務器僅緩沖 64 KiB 的(de)未使用請求正文。這(zhè)導緻讀取被限制在(zài)最大(dà)大(dà)小,這(zhè)會影響大(dà)型請求正文(例如大(dà)文件上(shàng)傳)時(shí)的(de)性能。在(zài) .NET 6 Preview 5 中,我們将默認緩沖區大(dà)小從 64 KiB 更改爲(wéi / wèi) 1 MiB,這(zhè)應該會提高大(dà)型上(shàng)傳的(de)吞吐量。在(zài)我們的(de)測試中,過去需要(yào / yāo) 9 秒的(de) 700 MiB 上(shàng)傳現在(zài)隻需 2.5 秒。

較大(dà)緩沖區大(dà)小的(de)缺點是(shì),當應用程序不(bù)能快速讀取請求正文時(shí),每個(gè)請求的(de)内存消耗會增加。因此,除了(le/liǎo)更改默認緩沖區大(dà)小外,我們還使緩沖區大(dà)小可配置,允許您根據工作負載進行調整。

public void ConfigureServices(IServiceCollection services)
{
    services.Configure(
        options =>
        {
            options.MaxRequestBodySize = 64 * 1024;
        }
    );
}

給予反饋

我們希望您喜歡 .NET 6 中 ASP.NET Core 的(de)這(zhè)個(gè)預覽版本。我們很想知道(dào)您對這(zhè)個(gè)版本的(de)體驗。通過在(zài)GitHub 上(shàng)提交問題讓我們知道(dào)您的(de)想法。

感謝您試用 ASP.NET Core!



來(lái)源:DotNET技術圈