Share via


ASP.NET Core 5.0 的新功能

本文會重點介紹 ASP.NET Core 5.0 中最重要的變更,並隨附相關文件的連結。

ASP.NET Core MVC 和 Razor 改進事項

將 DateTime 模型繫結為 UTC

模型繫結現在支援將 UTC 時間字串繫結至 DateTime。 如果要求中包含 UTC 時間字串,模型繫結會將它繫結至 UTC DateTime。 例如,下列時間字串會繫結 UTC DateTimehttps://example.com/mycontroller/myaction?time=2019-06-14T02%3A30%3A04.0576719Z

使用 C# 9 記錄類型進行模型繫結和驗證

C# 9 記錄類型可以與 MVC 控制器或 Razor Page 中的模型繫結搭配使用。 記錄類型是一種用來模擬網路傳輸資料的好方法。

例如,下列 PersonController 會使用 Person 記錄類型來搭配模型繫結和表單驗證:

public record Person([Required] string Name, [Range(0, 150)] int Age);

public class PersonController
{
   public IActionResult Index() => View();

   [HttpPost]
   public IActionResult Index(Person person)
   {
          // ...
   }
}

Person/Index.cshtml 檔案:

@model Person

Name: <input asp-for="Model.Name" />
<span asp-validation-for="Model.Name" />

Age: <input asp-for="Model.Age" />
<span asp-validation-for="Model.Age" />

DynamicRouteValueTransformer 的改進事項

ASP.NET Core 3.1 引入了 DynamicRouteValueTransformer,作為使用自訂端點來動態選取 MVC 控制器動作或 Razor 頁面的方法。 ASP.NET Core 5.0 應用程式可以將狀態傳遞至 DynamicRouteValueTransformer,並篩選所選的端點集。

其他

  • [Compare] 屬性可以套用至 Razor Page 模型上的屬性。
  • 根據預設,繫結自主體的參數和屬性會被視為必要項目。

Web API

預設開啟 OpenAPI 規格

OpenAPI 規格是一種業界標準,用於描述 HTTP API 並將其整合到複雜的商務程序中或與第三方整合。 OpenAPI 廣受各類雲端提供者和許多 API 登錄所支援。 從 Web API 發出 OpenAPI 文件的應用程式有多種可以使用這些 API 的新機會。 因與開放原始碼專案 Swashbuckle.AspNetCore 的維護者合作,ASP.NET Core API 範本包含了對 Swashbuckle 的 NuGet 相依性。 Swashbuckle 是一種熱門的開放原始碼 NuGet 套件,可動態發出 OpenAPI 文件。 Swashbuckle 透過對 API 控制器進行內省,並在執行階段或於使用 Swashbuckle CLI 進行建置時產生 OpenAPI 文件來實現此目的。

在 ASP.NET Core 5.0 中,Web API 範本預設會啟用 OpenAPI 支援。 若要停用 OpenAPI:

  • 從命令列:

      dotnet new webapi --no-openapi true
    
  • 從 Visual Studio:取消核取 [啟用 OpenAPI 支援]

針對 Web API 專案建立的所有 .csproj 檔案都包含 Swashbuckle.AspNetCore NuGet 套件參考。

<ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
</ItemGroup>

範本產生的程式碼在 Startup.ConfigureServices 中包含了啟動 OpenAPI 文件產生作業的程式碼:

public void ConfigureServices(IServiceCollection services)
{

    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApp1", Version = "v1" });
    });
}

Startup.Configure 方法會新增 Swashbuckle 中介軟體,以啟用:

  • 文件產生程序。
  • 預設為開發模式下的 Swagger UI 頁面。

發佈至生產環境時,範本產生的程式碼並不會意外公開 API 的描述。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();  // UseSwaggerUI Protected by if (env.IsDevelopment())
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
                         "WebApp1 v1"));
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Azure API 管理匯入

ASP.NET Core API 專案啟用 OpenAPI 時,Visual Studio 2019 16.8 版和更新版本會自動在發佈流程中提供額外的步驟。 使用 Azure API 管理的開發人員可伺機在發佈流程期間自動將 API 匯入 Azure API 管理:

Azure API Management Import VS publishing

更好的 Web API 專案啟動體驗

依預設啟用 OpenAPI 時,Web API 開發人員的應用程式啟動體驗 (F5) 會大幅改善。 在 ASP.NET Core 5.0 中,Web API 範本已預先設定為載入 Swagger UI 頁面。 Swagger UI 頁面提供了為已發佈的 API 新增的兩類文件,只需按一下即可測試 API。

swagger/index.html view

Blazor

效能改善

對於 .NET 5,我們大幅改善了 Blazor WebAssembly 執行階段效能,特別著重於複雜的 UI 呈現和 JSON 序列化。 在我們的效能測試中,.NET 5 中的 Blazor WebAssembly 在大多數情況下速度要快上兩到三倍。 如需詳細資訊,請參閱 ASP.NET 部落格:.NET 5 候選版 1 中的 ASP.NET Core 更新

CSS 隔離

Blazor 現在支援定義限定於指定元件的 CSS 樣式。 元件專用 CSS 樣式可讓您更輕鬆地推理應用程式中的樣式,並避免全域樣式的意外副作用。 如需詳細資訊,請參閱 ASP.NET Core Blazor CSS 隔離

新的 InputFile 元件

InputFile 元件可讀取使用者選取的一或多個檔案以進行上傳。 如需詳細資訊,請參閱 ASP.NET Core Blazor 檔案上傳

新的 InputRadioInputRadioGroup 元件

Blazor 內建有 InputRadioInputRadioGroup 元件,可透過整合式驗證來簡化選項按鈕群組的資料繫結。 如需詳細資訊,請參閱 ASP.NET 核心 Blazor 輸入元件

元件虛擬化

使用 Blazor 架構的內建虛擬化支援,改善元件轉譯的感知效能。 如需詳細資訊,請參閱 ASP.NET Core Razor 元件虛擬化

ontoggle 事件支援

Blazor 事件現在支援 ontoggle DOM 事件。 如需詳細資訊,請參閱 ASP.NET Core Blazor 事件處理

在 Blazor 應用程式中設定 UI 焦點

對元素參考使用 FocusAsync 便利方法,將 UI 焦點設定為該元素。 如需詳細資訊,請參閱 ASP.NET Core Blazor 事件處理

自訂驗證 CSS 類別屬性

與 CSS 架構 (例如 Bootstrap) 整合時,自訂驗證 CSS 類別屬性會很有用。 如需詳細資訊,請參閱核心窗體驗證 ASP.NETBlazor。

IAsyncDisposable 支援

Razor 元件現在支援 IAsyncDisposable 介面,用於非同步釋放已配置的資源。

JavaScript 隔離和物件參考

Blazor 可在標準 JavaScript 模組中啟用 JavaScript 隔離。 如需詳細資訊,請參閱從 ASP.NET Core Blazor 中的 .NET 方法呼叫 JavaScript 函式

表單元件支援顯示名稱

下列內建元件支援使用 DisplayName 參數顯示名稱:

  • InputDate
  • InputNumber
  • InputSelect

如需詳細資訊,請參閱核心窗體概觀 ASP.NETBlazor。

Catch-all 路由參數

元件中支援會跨多個資料夾界限擷取路徑的 Catch-all 路由參數。 如需詳細資訊,請參閱 ASP.NET Core Blazor 路由和瀏覽

偵錯改進

ASP.NET Core 5.0 中已改善 Blazor WebAssembly 應用程式的偵錯。 此外,Visual Studio for Mac 現在已支援偵錯。 如需詳細資訊,請參閱偵錯 ASP.NET Core Blazor 應用程式

Microsoft Identity v2.0 和 MSAL v2.0

Blazor 安全性現在使用 Microsoft Identity v2.0 (Microsoft.Identity.WebMicrosoft.Identity.Web.UI) 和 MSAL v2.0。 如需詳細資訊,請參閱Blazor 安全性和 Identity 節點 中的主題。

Blazor Server 的受保護瀏覽器儲存體

Blazor Server 應用程序現在可以使用內建支援,將使用 ASP.NET Core 資料保護來防止篡改的應用程式狀態儲存至瀏覽器中。 資料可以儲存在本機瀏覽器儲存體或工作階段儲存體中。 如需詳細資訊,請參閱 ASP.NET Core Blazor 狀態管理

Blazor WebAssembly 預先呈現

元件整合在不同的裝載模式下已獲改善,Blazor WebAssembly 應用程式現在可以在服務器上預先呈現輸出。

修剪/連結改善

Blazor WebAssembly 會在建置期間執行中繼語言 (IL) 修剪/連結,以從應用程式的輸出組件中修剪非必要的 IL。 隨著 ASP.NET Core 5.0 的發行,Blazor WebAssembly 會透過其他組態選項執行改良的修剪。 如需詳細資訊,請參閱設定 ASP.NET Core Blazor 的修剪器修剪選項

瀏覽器相容性分析器

Blazor WebAssembly 應用程式會鎖定完整的.NET API 表面區域,但受限於瀏覽器沙箱,WebAssembly 並不支援所有的 .NET API。 在 WebAssembly 上執行時,不支援的 API 會擲回 PlatformNotSupportedException。 當應用程式使用了其目標平台不支援的 API 時,平台相容性分析器即會警告開發人員。 如需詳細資訊,請參閱從 Razor 類別庫 (RCL) 取用 ASP.NET Core Razor

消極式載入組件

Blazor WebAssembly 應用程式的啟動效能可以透過延遲載入一些應用程式組件,直到需要時才加以載入,據此來進行改善。 如需詳細資訊,請參閱 ASP.NET Core Blazor WebAssembly 中的消極式載入組件

更新的全球化支援

根據 Unicode 的國際元件 (ICU),Blazor WebAssembly 可以使用全球化支援。 如需詳細資訊,請參閱 ASP.NET Core Blazor 全球化和當地語系化

gRPC

gRPC 中已進行許多效能改善。 如需詳細資訊,請參閱 .NET 5 中的 gRPC 效能改善

如需 gRPC 的詳細資訊,請參閱 .NET 上的 gRPC 概觀

SignalR

SignalR 中樞篩選條件

SignalR 中樞篩選條件 (在 ASP.NET SignalR 中稱為中樞管線) 是一項功能,可讓程式碼在呼叫中樞方法之前和之後執行。 在呼叫中樞方法之前和之後執行程式碼,與中介軟體有能力在 HTTP 要求之前和之後執行程式碼的情況類似。 常見的用途包括記錄、錯誤處理和引數驗證。

如需詳細資訊,請參閱 在 ASP.NET Core SignalR 中使用中樞篩選條件

SignalR 平行中樞引動過程

ASP.NET Core SignalR 現在能夠處理平行中樞引動過程。 您可以變更預設行為,允許用戶端一次叫用多個中樞方法:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(options =>
    {
        options.MaximumParallelInvocationsPerClient = 5;
    });
}

SignalR JAVA 用戶端中新增的 Messagepack 支援

有個新套件 (com.microsoft.signalr.messagepack) 為 SignalR JAVA 用戶端增添了 MessagePack 支援能力。 若要使用 MessagePack 中樞通訊協定,請將 .withHubProtocol(new MessagePackHubProtocol()) 新增至連線建立器:

HubConnection hubConnection = HubConnectionBuilder.create(
                           "http://localhost:53353/MyHub")
               .withHubProtocol(new MessagePackHubProtocol())
               .build();

Kestrel

  • 可透過組態重載的端點:Kestrel 可以偵測傳遞給 KestrelServerOptions.Configure 的組態變更,並從現有端點解除繫結後再繫結至新的端點,而不需要在 reloadOnChange 參數為 true 時重新啟動應用程式。 根據預設,使用 ConfigureWebHostDefaultsCreateDefaultBuilder 時,Kestrel 會繫結至已啟用 reloadOnChange"Kestrel" 組態子區段。 應用程式必須在手動呼叫 KestrelServerOptions.Configure 時傳遞 reloadOnChange: true,才能取得可重載的端點。

  • HTTP/2 回應標頭改善。 如需詳細資訊,請參閱下一節中的效能改善

  • 支援通訊端傳輸中的其他端點類型:除了 System.Net.Sockets 中引入的新 API 之外,Kestrel 中的通訊端預設傳輸 Kestrel 允許繫結至現有的檔案控制代碼和 Unix 網域通訊端。 支援繫結至現有檔案控制代碼,可讓您使用現有的 Systemd 整合,而不需要 libuv 傳輸。

  • Kestrel 中的自訂標頭解碼:應用程式可以根據標頭名稱指定使用哪個 Encoding 來解譯傳入標頭,而不是預設為 UTF-8。 設定 Microsoft.AspNetCore.Server.Kestrel.KestrelServerOptions.RequestHeaderEncodingSelector 屬性,以指定要使用的編碼方式:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
          .ConfigureWebHostDefaults(webBuilder =>
          {
              webBuilder.ConfigureKestrel(options =>
              {
                  options.RequestHeaderEncodingSelector = encoding =>
                  {
                        return encoding switch
                        {
                            "Host" => System.Text.Encoding.Latin1,
                            _ => System.Text.Encoding.UTF8,
                        };
                  };
              });
              webBuilder.UseStartup<Startup>();
          });
    

透過組態的 Kestrel 端點專用選項

新增了透過組態來設定 Kestrel 的端點專用選項的支援。 端點專用組態包括:

  • 所用的 HTTP 通訊協定
  • 所用的 TLS 通訊協定
  • 選取的憑證
  • 用戶端憑證模式

組態可供您根據指定的伺服器名稱來指定要選取的憑證。 伺服器名稱是伺服器名稱指示 (SNI) 延伸模組的一部分,後者來自用戶端所指明的 TLS 通訊協定。 Kestrel 的組態也支援在主機名稱中使用萬用字元前置詞。

下列範例示範如何使用組態檔來指定端點專有事項:

{
  "Kestrel": {
    "Endpoints": {
      "EndpointName": {
        "Url": "https://*",
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": [ "Tls11", "Tls12"],
            "Certificate": {
              "Path": "testCert.pfx",
              "Password": "testPassword"
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "testCert2.pfx",
              "Password": "testPassword"
            }
          },
          "*": {
            // At least one sub-property needs to exist per
            // SNI section or it cannot be discovered via
            // IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    }
  }
}

伺服器名稱指示 (SNI) 是 TLS 延伸模組,可包含虛擬網域作為 SSL 交涉的一部分。 這實際上表示虛擬網域名稱或主機名稱可用於識別網路端點。

效能改善

HTTP/2

  • 大幅減少 HTTP/2 程式碼路徑中的配置。

  • 支援 Kestrel 中 HTTP/2 回應標頭的 HPack 動態壓縮。 如需詳細資訊,請參閱標頭資料表大小HPACK:HTTP/2 的無訊息殺手 (功能)

  • 傳送 HTTP/2 PING 框架:HTTP/2 有一種傳送 PING 框架的機制,以確保閒置連線仍可正常運作。 確保連線可行性對用到經常閒置但偶有活動的長期資料流而言特別有用,例如 gRPC 資料流。 應用程式可以藉由對 KestrelServerOptions 設定限制,在 Kestrel 中傳送定期 PING 框架:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
          .ConfigureWebHostDefaults(webBuilder =>
          {
              webBuilder.ConfigureKestrel(options =>
              {
                  options.Limits.Http2.KeepAlivePingInterval =
                                                 TimeSpan.FromSeconds(10);
                  options.Limits.Http2.KeepAlivePingTimeout =
                                                 TimeSpan.FromSeconds(1);
              });
              webBuilder.UseStartup<Startup>();
          });
    

容器

在 .NET 5.0 之前,建置和發佈適用於 ASP.NET Core 應用程式的 Dockerfile 需要提取整個 .NET Core SDK 和 ASP.NET Core 映像。 在這個版本中,提取 SDK 映像的位元組數量減少了,而提取 ASP.NET Core 映像的位元組數量幾乎已消除。 如需詳細資訊,請參閱這個 GitHub 問題註解

驗證和授權

使用 Microsoft.Identity.Web 進行 Microsoft Entra ID 驗證

ASP.NET Core 專案範本現在會與 Microsoft.Identity.Web 整合,以處理 Microsoft Entra ID 的驗證。 Microsoft.Identity.Web 套件提供:

  • 透過 Microsoft Entra ID 進行驗證的更佳體驗。
  • 更能輕鬆代表使用者存取 Azure 資源的方式,包括 Microsoft Graph。 請參閱 Microsoft.Identity.Web 範例,從基本登入開始,然後逐步實作多租用戶、使用 Azure API、使用 Microsoft Graph 以及保護您自己的 API。 Microsoft.Identity.Web 會隨 .NET 5 一併提供。

允許匿名存取端點

AllowAnonymous 擴充方法允許匿名存取端點:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        })
        .AllowAnonymous();
    });
}

自訂授權失敗處理方式

現在,透過授權中介軟體所叫用的全新 IAuthorizationMiddlewareResultHandler 介面,可以更輕鬆地自訂授權失敗處理方式。 預設實作會維持不變,但可以在 [相依性插入] 中註冊自訂處理常式,這允許根據授權失敗的原因來自訂 HTTP 回應。 請參閱此範例,為您示範 IAuthorizationMiddlewareResultHandler 的用法。

使用端點路由時的授權

使用端點路由進行授權時,現在會收到 HttpContext 而不是端點執行個體。 這可讓授權中介軟體存取 RouteData 以及無法透過 Endpoint 類別存取的 HttpContext 的其他屬性。 您可以使用 context.GetEndpoint 從內容擷取端點。

Linux 上使用 Kerberos 驗證和 LDAP 的角色型存取控制

請參閱 Kerberos 驗證和角色型存取控制 (RBAC)

API 改善

HttpRequest 和 HttpResponse 的 JSON 擴充方法

您可以使用新的 ReadFromJsonAsyncWriteAsJsonAsync 擴充方法,對 HttpRequestHttpResponse 進行 JSON 資料的讀取和寫入。 這些擴充方法會使用 System.Text.Json 序列化程式來處理 JSON 資料。 新的 HasJsonContentType 擴充方法也可以檢查一要求是否具有 JSON 內容類型。

JSON 擴充方法可以結合端點路由,以我們稱為路由至程式碼的程式設計樣式來建立 JSON API。 對於想要以輕量型方式建立基本 JSON API 的開發人員來說,這是一個新選項。 例如,僅具有少量端點的 Web 應用程式可能會選擇使用路由至程式碼,而不是 ASP.NET Core MVC 的完整功能:

endpoints.MapGet("/weather/{city:alpha}", async context =>
{
    var city = (string)context.Request.RouteValues["city"];
    var weather = GetFromDatabase(city);

    await context.Response.WriteAsJsonAsync(weather);
});

System.Diagnostics.Activity

System.Diagnostics.Activity 的預設格式現在是預設為 W3C 格式。 這使得 ASP.NET Core 中的分散式追蹤支援會預設成與更多架構互通。

FromBodyAttribute

FromBodyAttribute 現在支援設定選項,允許將這些參數或屬性視為選用:

public IActionResult Post([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]
                          MyModel model)
{
    ...
}

其他改進項目

我們已開始將可為 Null 的註釋套用至 ASP.NET Core 組件。 我們計畫對 .NET 5 架構常見的大部分公用 API 介面進行註解。

控制啟動類別啟用

已新增額外的 UseStartup 多載,可讓應用程式提供 Factory 方法來控制 Startup 類別啟用。 控制 Startup 類別啟用有助於將其他參數傳遞給隨主機一起初始化的 Startup

public class Program
{
    public static async Task Main(string[] args)
    {
        var logger = CreateLogger();
        var host = Host.CreateDefaultBuilder()
            .ConfigureWebHost(builder =>
            {
                builder.UseStartup(context => new Startup(logger));
            })
            .Build();

        await host.RunAsync();
    }
}

使用 dotnet watch 自動重新整理

於 .NET 5 中,在 ASP.NET Core 專案上執行 dotnet watch 即會啟動預設瀏覽器,並在變更了程式碼時自動重新整理瀏覽器。 這表示您可以:

  • 在文字編輯器中開啟 ASP.NET Core 專案。
  • 執行 dotnet watch
  • 專注於程式碼變更,讓工具處理重建、重新啟動和重新載入應用程式。

主控台記錄器格式器

Microsoft.Extensions.Logging 程式庫中的主控台記錄提供者已獲改善。 開發人員現在可以實作自訂的 ConsoleFormatter,以完全控制主控台輸出的格式和色彩。 格式器 API 允許透過實作 VT-100 逸出序列的子集來實現豐富的格式化。 大多數新式終端都支援 VT-100。 主控台記錄器可以在不支援的終端上剖析逸出序列,讓開發人員為所有終端撰寫單一格式器。

JSON 主控台記錄器

除了支援自訂格式器之外,我們也已新增了內建的 JSON 格式器,可將結構化 JSON 記錄發送至主控台。 下列程式碼示範如何從預設記錄器切換到 JSON:

public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
  .ConfigureLogging(logging =>
  {
     logging.AddJsonConsole(options =>
     {
         options.JsonWriterOptions = new JsonWriterOptions()
         { Indented = true };
     });
  })
  .ConfigureWebHostDefaults(webBuilder =>
  {
    webBuilder.UseStartup<Startup>();
  });

發送至主控台的記錄訊息會採用 JSON 格式:

{
  "EventId": 0,
  "LogLevel": "Information",
  "Category": "Microsoft.Hosting.Lifetime",
  "Message": "Now listening on: https://localhost:5001",
  "State": {
    "Message": "Now listening on: https://localhost:5001",
    "address": "https://localhost:5001",
    "{OriginalFormat}": "Now listening on: {address}"
  }
}