...

.NET 6 Preview 5 中的 ASP.NET Core 更新

2021-06-29

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

.NET 6 Preview 5 現已推出,其中包括對(duì) ASP.NET Core 的許多重大改進(jìn)。

以下是此預覽版中的新功能(néng):

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

開(kāi)始

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

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

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

注意:Visual Studio 2022 預覽版 1 尚不支持 .NET MAUI。對(duì)于 .NET MAUI 開(kāi)發(fā),請改用 Visual Studio 2019 16.11 的最新預覽版。

要安裝用于提前 (AOT) 編譯和運行時(shí)重新鏈接的最新 .NET WebAssembly 工具,請從提升的命令提示符運行以下命令:

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

如果您之前安裝了 .NET WebAssembly 工作負載,您可以通過(guò)從提升的命令提示符運行以下命令將(jiāng)其更新到 .NET 6 Preview 5:

dotnet workload update

注意:使用 Visual Studio 2022 Preview 1 附帶的 .NET 6 Preview 5 SDK 安裝可選 SDK 工作負載存在一個已知問題。要解決此問題,請從 https://dot.net/ 安裝 .NET 6 Preview 5 SDK安裝 Visual Studio 2022 預覽版 1 後(hòu)的 get-dotnet6。

升級現有項目

要將(jiāng)現有的 ASP.NET Core 應用程序從 .NET 6 Preview 4 升級到 .NET 6 Preview 5:

  • 將(jiāng)所有 Microsoft.AspNetCore.* 包引用更新爲.6.0.0-preview.5.*
  • 將(jiāng)所有 Microsoft.Extensions.* 包引用更新爲.6.0.0-preview.5.*

要將(jiāng) .NET MAUI Blazor 應用從 .NET 6 Preview 4 升級到 .NET 6 Preview 5,我們建議從使用 .NET 6 Preview 5 SDK 創建的新 .NET MAUI Blazor 項目開(kāi)始,然後(hòu)從原始項目複制代碼。

查看 .NET 6 的 ASP.NET Core 重大變更的完整列表。

.NET 熱重載更新 dotnet watch

我們一直緻力于對(duì) .NET 6 的 .NET Hot Reload 進(jìn)行各種(zhǒng)改進(jìn)。其中一些改進(jìn)在 .NET 6 Preview 5 中可用,而其他改進(jìn)仍在進(jìn)行中,將(jiāng)在未來的預覽更新中完善。

您不再需要在 launchSettings.json 中指定hotReloadProfile 以使用dotnet watch 來啓用 .NET Hot Reload . 能(néng)夠支持熱重載的項目現在會(huì)默認啓用 .NET 熱重載。

當進(jìn)行了無法熱重載的代碼編輯(“粗魯”編輯)時(shí),dotnet watch現在將(jiāng)詢問您是否要重新啓動應用程序以應用更改:

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è)些選項具有以下行爲:

  • 選擇  將(jiāng)重新啓動應用程序。
  • 選擇  不會(huì)重新啓動應用程序,并且會(huì)保持應用程序運行而不應用更改。
  • 當無法熱重新加載更改時(shí),選擇“*始終”*將(jiāng)根據需要重新啓動應用程序。
  • 選擇 從不 不會(huì)重新啓動應用程序并避免將(jiāng)來出現提示。

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

注意:此版本中存在一個已知問題,即選擇“*始終”*仍會(huì)繼續提示將(jiāng)來進(jìn)行粗魯編輯。這(zhè)將(jiāng)在未來的預覽版本中得到解決。

要在使用時(shí)禁用對(duì) .NET Hot Reload 的支持dotnet watch,請使用命令行選項。--no-hot-reload

使用 dotnet watch 進(jìn)行 .NET Hot Reload 現在也將(jiāng)正确檢測 Blazor WebAssembly 應用程序中的“粗魯”編輯。當刷新浏覽器或在單獨的浏覽器 Tab 或浏覽器實例中加載應用程序時(shí),應用于 Blazor WebAssembly 應用程序的更改將(jiāng)重新應用于應用程序。

ASP.NET Core SPA 模闆更新到 Angular 11 和 React 17

用于 Angular 和 React 的 ASP.NET Core 單頁應用 (SPA) 模闆已更新爲 Angular 11 和 React 17。我們還(hái)希望在未來的 .NET 6 預覽版中將(jiāng) Angular 模闆進(jìn)一步更新爲 Angular 12,因爲 Angular 12 已經(jīng)正式發(fā)布了。

在 SVG foreignObject元素中支持 Razor 語法

您現在可以在 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!";
}

我們還(hái)進(jìn)行了大量驗證和測試,以确保 Blazor 對(duì) SVG 場景有良好(hǎo)的支持。我們認爲 Blazor 的 SVG 支持現在處于良好(hǎo)狀态。如果您在此版本的 Blazor 中使用 SVG 遇到任何問題,請通過(guò)在GitHub 上創建 Issue 告訴我們。

ActionRenderFragment組件參數指定 null

現在,您可以指定Blazor組件參數值ActionRenderFragment爲 null,從而簡化采取可選的回調參數或模闆參數的新組件。

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

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

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

不需要全球化功能(néng)的 .NET 應用程序可以選擇不要它,通過(guò)在其項目文件中設置InvariantGlobalization屬性爲true來使用不變的全球化。在 .NET 5 中,這(zhè)將(jiāng)允許 Blazor WebAssembly 應用程序避免下載全球化數據,但仍會(huì)包含 .NET 運行時(shí)中的相關邏輯。

在 .NET 6 Preview 5 中,您現在可以使用 .NET WebAssembly 工具(與用于 .NET WebAssembly AOT 編譯的工具相同)重新鏈接運行時(shí)以删除不需要的邏輯并顯著(zhe)減小運行時(shí)的大小。如果您安裝了 .NET WebAssembly 工作負載,則在您發(fā)布應用程序時(shí)會(huì)自動完成(chéng)運行時(shí)重新鏈接。使用不變全球化模式時(shí),大小減少尤其顯著(zhe)。

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

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

下表顯示了使用 .NET 5 和 .NET 6 的默認 Blazor WebAssembly 項目的dotnet.wasm傳輸大小:

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

在 Json.NET 輸出格式化程序中寫入磁盤之前可配置的緩沖區阈值

默認情況下,Newtonsoft.Json 輸出格式化程序(output formatter)在緩沖到磁盤之前在内存中緩沖高達 32 KiB 的響應。這(zhè)是爲了避免執行同步 IO,但是這(zhè)會(huì)導緻其他副作用,例如線程饑餓和應用程序死鎖。但是,如果您的響應大于 32 KiB,則會(huì)導緻大量可避免的磁盤 I/O。您現在可以在緩沖到磁盤之前配置内存阈值。

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

注意:我們仍然建議使用 System.Text.Json output formatter,除非出于兼容性原因需要 Newtonsoft.Json 序列化程序。System.Text.Json 序列化程序是完全異步的,將(jiāng)有效地适用于任何大小的有效載荷。

用于更好(hǎo)地過(guò)濾 Kestrel 日志的子類别

在此更改之前,爲 Kestrel 啓用詳細日志記錄非常昂貴,因爲所有 Kestrel 共享相同的日志記錄類别名稱 (Microsoft.AspNetCore.Server.Kestrel )。我們現在將(jiāng)該類别拆分爲多個新的子類别:

  • 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。

雖然您現有的規則將(jiāng)繼續有效(日志過(guò)濾應用具有最長(cháng)匹配類别前綴的規則),但您現在可以更有選擇性地選擇啓用哪些規則。例如,使用 Debug爲 bad requests 啓用日志記錄的可觀察性開(kāi)銷大大降低,可以通過(guò)以下配置實現:

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

更快地獲取和設置 HTTP 頭

我們添加了新的 API 以將(jiāng) System.Net.Http.HeaderNames 所有可用的通用标頭公開(kāi)爲屬性,從而使 Microsoft.AspNetCore.Http.IHeaderDictionary API 更易于使用。例如,下面(miàn)的内聯中間件使用新 API 獲取/設置請求和響應标頭:

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

對(duì)于已實現的标頭,get/set訪問器是通過(guò)直接轉到字段并繞過(guò)查找來實現的。對(duì)于未實現的标頭,訪問者可以繞過(guò)針對(duì)已實現标頭的初始查找并直接執行查找 Dictionary。這(zhè)導緻兩(liǎng)種(zhǒng)情況下的訪問速度更快。

方法分支類型平均操作/秒Delta
GetHeaders預覽4純文本25.793 納秒38,770,569.6——
GetHeaders預覽5純文本12.775 納秒78,279,480.0+101.9%
GetHeaders預覽4常見的121.355 納秒8,240,299.3——
GetHeaders預覽5常見的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常見的635.060 納秒1,574,654.3——
SetHeaders預覽5常見的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 的可配置未消耗傳入緩沖區大小

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

較大緩沖區大小的缺點是,當應用程序不能(néng)快速讀取請求正文時(shí),每個請求的内存消耗會(huì)增加。因此,除了更改默認緩沖區大小外,我們還(hái)使緩沖區大小可配置,允許您根據工作負載進(jìn)行調整。

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

給予反饋

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

感謝您試用 ASP.NET Core!



來源:DotNET技術圈