天天看點

「譯」.NET 7 預覽版 1 中的 ASP.NET Core 更新

原文 | Daniel Roth

翻譯 | 鄭子銘

.NET 7 預覽版 1 現已推出!這是 .NET 下一個主要版本的第一個預覽版,其中将包括使用 ASP.NET Core 進行 Web 開發的下一波創新。

在 .NET 7 中,我們計劃對 ASP.NET Core 進行廣泛投資。以下是我們計劃重點關注的一些領域:

  • 性能:.NET 6 包含對 ASP.NET Core 的許多性能改進,我們将努力使 ASP.NET Core 在 .NET 7 中更快、更高效。
  • HTTP/3:HTTP/3 支援作為 .NET 6 中的預覽功能提供。對于 .NET 7,我們希望完成它并使其成為預設啟用的受支援功能。在未來的預覽版中,您可以期待在我們的 HTTP/3 支援中看到進階 TLS 功能和更多性能改進。
  • 最小 API:添加對端點過濾器和路由分組的支援,作為最小 API 的核心原語。通常還簡化 API 的身份驗證和授權配置。
  • gRPC:我們正在投資 gRPC JSON 轉碼。此功能允許 gRPC 服務像帶有 JSON 請求和響應的 RESTful HTTP API 一樣被調用。
  • SignalR:添加對強類型用戶端的支援并從用戶端調用傳回結果。
  • Razor:我們将對 Razor 編譯器進行各種改進,以提高性能、彈性并促進改進的工具。
  • Blazor:在完成對 .NET MAUI、WPF 和 Windows 窗體的 Blazor Hybrid 支援後,我們将對 Blazor 進行廣泛的改進,包括:新的 .NET WebAssembly 功能:混合模式 AOT、多線程、Web 加密。增強的熱重載支援。資料綁定改進。更靈活的預渲染。更好地控制 Blazor 伺服器電路的生命周期。改進了對微前端的支援。
  • MVC:對端點路由、連結生成和參數綁定的改進。
  • Orleans:ASP.NET Core 和 Orleans 團隊正在研究進一步調整和內建 Orleans 分布式程式設計模型與 ASP.NET Core 的方法。 Orleans 4 将與 .NET 7 一起釋出,并專注于簡單性、可維護性和性能,包括人類可讀的流辨別和新的優化、版本容忍的序列化程式。

有關為 .NET 7 計劃的特定 ASP.NET Core 工作的更多詳細資訊,請參閱 GitHub 上針對 .NET 7 的完整 ASP.NET Core 路線圖。

.NET 7 Preview 1 是衆多 .NET 7 預覽版中的第一個,為 2022 年 11 月的 .NET 7 版本做準備。

我在最近一集 On .NET 中加入了 James Montemagno,以分解 .NET 7 和 .NET 7 中的 ASP.NET Core 中的所有内容:

以下是此預覽版中新增内容的摘要:

  • 最小的 API 改進:IFormFile 和 IFormFileCollection 支援将請求正文綁定為 Stream 或 PipeReaderJSON 選項配置
  • SignalR 用戶端源生成器
  • 支援 MVC 視圖和 Razor 頁面中的可為空模型
  • 在驗證錯誤中使用 JSON 屬性名稱
  • 改進了 dotnet watch 的控制台輸出
  • 将 dotnet watch 配置為始終重新啟動以進行粗魯的編輯
  • 在 ValidationAttribute 中使用依賴注入
  • 更快的标頭解析和寫入
  • gRPC JSON 轉碼

開始使用

要開始使用 .NET 7 Preview 1 中的 ASP.NET Core,請安裝 .NET 7 SDK。

如果您在 Windows 上使用 Visual Studio,我們建議安裝最新的 Visual Studio 2022 預覽版。 Visual Studio for Mac 對 .NET 7 預覽的支援尚不可用,但即将推出。

要安裝最新的 .NET WebAssembly 建構工具,請從提升的指令提示符處運作以下指令:

dotnet workload install wasm-tools
           

更新現有項目

要将現有的 ASP.NET Core 應用從 .NET 6 更新到 .NET 7 Preview 1:

  • 将您的應用程式的目标架構更新為 net7.0。
  • 将所有 Microsoft.AspNetCore.* 包引用更新到 7.0.0-preview.1.*。
  • 将所有 Microsoft.Extensions.* 包引用更新到 7.0.0-preview.1.*。

另請參閱 .NET 7 的 ASP.NET Core 中的重大更改的完整清單。

最小的 API 改進

IFormFile 和 IFormFileCollection 支援

您現在可以使用 IFormFile 和 IFormFileCollection 在最少的 API 中處理檔案上傳:

app.MapPost("/upload", async(IFormFile file) =>
{
    using var stream = System.IO.File.OpenWrite("upload.txt");
    await file.CopyToAsync(stream); 
});
           
app.MapPost("/upload", async (IFormFileCollection myFiles) => { ... });
           

将此功能與身份驗證一起使用需要防僞支援,但尚未實作。我們的 .NET 7 路線圖包含對最小 API 的防僞支援。當請求包含 Authorization 标頭、用戶端證書或 cookie 标頭時,綁定到 IFormFile 或 IFormFileCollection 目前被禁用。我們将在完成防僞支援工作後立即解決此限制。

感謝 @martincostello 貢獻此功能。

将請求正文綁定為 Stream 或 PipeReader

您現在可以将請求正文綁定為 Stream 或 PipeReader,以有效地支援使用者必須攝取資料并将其存儲到 blob 存儲或将資料排隊到隊列提供程式(Azure 隊列等)以供以後處理的場景工作者或雲功能。以下示例顯示了如何使用新綁定:

app.MapPost("v1/feeds", async (QueueClient queueClient, Stream body, CancellationToken cancellationToken) =>
{
    await queueClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken);
    await queueClient.SendMessageAsync(await BinaryData.FromStreamAsync(body), cancellationToken: cancellationToken);
});
           

使用 Stream 或 PipeReader 時,需要考慮以下幾點:

  • 攝取資料時,Stream 将是與 HttpRequest.Body 相同的對象。
  • 預設情況下不緩沖請求正文。讀取正文後,它不可回退(您不能多次讀取流)。
  • Stream/PipeReader 在最小操作處理程式之外不可用,因為底層緩沖區将被釋放和/或重用。

JSON 選項配置

我們正在引入一個新的更簡潔的 API,ConfigureRouteHandlerJsonOptions,為最小的 API 端點配置 JSON 選項。這個新的 API 避免了與 Microsoft.AspNetCore.Mvc.JsonOptions 的混淆。

var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureRouteHandlerJsonOptions(options =>
{
    //Ignore Cycles
    options.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; 
});   
           

感謝@mehmetakbulut 的貢獻,我們為 SignalR 添加了一個新的用戶端源生成器。

SignalR 用戶端源生成器根據您定義的接口生成強類型的發送和接收代碼。您可以在用戶端上重用來自強類型 SignalR 集線器的相同接口來代替松散類型的 .On("methodName", ...) 方法。同樣,您的集線器可以為其方法實作一個接口,并且用戶端可以使用該相同接口來調用集線器方法。

要使用 SignalR 用戶端源生成器:

  • 添加對 Microsoft.AspNetCore.SignalR.Client.SourceGenerator 包的引用。
  • 将 HubServerProxyAttribute 和 HubClientProxyAttribute 類添加到您的項目中(這部分設計可能會在未來的預覽版中更改):
[AttributeUsage(AttributeTargets.Method)]
internal class HubServerProxyAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Method)]
internal class HubClientProxyAttribute : Attribute
{
}
           
  • 為您的項目添加一個靜态分部類,并使用 [HubClientProxy] 和 [HubServerProxy] 屬性編寫靜态分部方法
internal static partial class MyCustomExtensions
{
    [HubClientProxy]
    public static partial IDisposable ClientRegistration<T>(this HubConnection connection, T provider);

    [HubServerProxy]
    public static partial T ServerProxy<T>(this HubConnection connection);
}
           
  • 使用代碼中的部分方法!
public interface IServerHub
{
    Task SendMessage(string message);
    Task<int> Echo(int i);
}

public interface IClient
{
    Task ReceiveMessage(string message);
}

public class Client : IClient
{
    // Equivalent to HubConnection.On("ReceiveMessage", (message) => {});
    Task ReceiveMessage(string message)
    {
        return Task.CompletedTask;
    }
}

HubConnection connection = new HubConnectionBuilder().WithUrl("...").Build();
var stronglyTypedConnection = connection.ServerProxy<IServerHub>();
var registrations = connection.ClientRegistration<IClient>(new Client());

await stronglyTypedConnection.SendMessage("Hello world");
var echo = await stronglyTypedConnection.Echo(10);
           

我們啟用了定義一個可為空的頁面或視圖模型來改進在 ASP.NET Core 應用中使用空狀态檢查時的體驗:

@model Product?
           

當模型驗證生成 ModelErrorDictionary 時,預設情況下它将使用屬性名稱作為錯誤鍵(“MyClass.PropertyName”)。模型屬性名稱通常是一個實作細節,這會使它們難以從單頁應用程式中處理。您現在可以将驗證配置為使用相應的 JSON 屬性名稱,而不是使用新的 SystemTextJsonValidationMetadataProvider(或使用 Json.NET 時的 NewtonsoftJsonValidationMetadataProvider)。

services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new SystemTextJsonValidationMetadataProvider())
});
           

我們清理了 dotnet watch 的控制台輸出,以更好地與 ASP.NET Core 的登出保持一緻,并在表情符号.中脫穎而出。

以下是新輸出的示例:

C:BlazorApp> dotnet watch
dotnet watch  Hot reload enabled. For a list of supported edits, see https://aka.ms/dotnet/hot-reload.
   Press "Ctrl + R" to restart.
dotnet watch  Building...
  Determining projects to restore...
  All projects are up-to-date for restore.
  You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  BlazorApp -> C:UsersdarothDesktopBlazorAppbinDebugnet7.0BlazorApp.dll
dotnet watch  Started
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:7148
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5041
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:UsersdarothDesktopBlazorApp
dotnet watch ⌚ File changed: .PagesIndex.razor.
dotnet watch  Hot reload of changes succeeded.
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
dotnet watch  Shutdown requested. Press Ctrl+C again to force exit.
           

通過将 DOTNET_WATCH_RESTART_ON_RUDE_EDIT 環境變量設定為 true,将 dotnet watch 配置為始終在不提示粗魯編輯(無法熱重新加載的編輯)的情況下重新啟動。

将服務注入 Blazor 中的自定義驗證屬性

您現在可以将服務注入 Blazor 中的自定義驗證屬性。 Blazor 将設定 ValidationContext,以便它可以用作服務提供者。

public class SaladChefValidatorAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var saladChef = validationContext.GetRequiredService<SaladChef>();
        if (saladChef.ThingsYouCanPutInASalad.Contains(value.ToString()))
        {
            return ValidationResult.Success;
        }
        return new ValidationResult("You should not put that in a salad!");
    }
}

// Simple class configured as a service for dependency injection
public class SaladChef
{
    public string[] ThingsYouCanPutInASalad = { "Strawberries", "Pineapple", "Honeydew", "Watermelon", "Grapes" };
}
           

感謝@MariovanZeist 的貢獻!

我們對 HTTP/2 和 HTTP/3 的标頭解析和寫入性能進行了多項改進。有關詳細資訊,請參閱以下拉取請求:

  • HTTP/2:提高傳入标頭性能
  • HTTP/3:優化驗證和設定傳入的标頭
  • HTTP 标頭枚舉器直接移至下一個

gRPC JSON 轉碼允許 gRPC 服務像 RESTful HTTP API 一樣使用。配置完成後,gRPC JSON 轉碼允許您使用熟悉的 HTTP 概念調用 gRPC 方法:

  • HTTP 動詞
  • URL參數綁定
  • JSON 請求/響應

當然 gRPC 也可以繼續使用。用于 gRPC 服務的 RESTful API。沒有重複!

ASP.NET Core 使用名為 gRPC HTTP API 的庫對此功能提供實驗性支援。對于 .NET 7,我們計劃将此功能作為 ASP.NET Core 的受支援部分。此功能尚未包含在 .NET 7 中,但您可以試用現有的實驗包。有關更多資訊,請參閱 gRPC HTTP API 入門文檔。

給予回報

我們希望您喜歡 .NET 7 中的 ASP.NET Core 預覽版,并且您對我們的 .NET 7 路線圖和我們一樣興奮!我們很想聽聽您對此版本的體驗以及您對路線圖的看法。通過在 GitHub 上送出問題并評論路線圖問題,讓我們知道您的想法。

感謝您試用 ASP.NET Core!

原文連結

ASP.NET Core updates in .NET 7 Preview 1