ASP.NET Core 3.0 的新功能

本文會重點說明 ASP.NET Core 3.0 最重要的變更,附有相關文件的連結。

Blazor

Blazor 是 ASP.NET Core 中用於建置互動式用戶端 Web UI 與 .NET 的新架構:

  • 使用 C# 建立豐富的互動式 UI。
  • 共用以 .NET 撰寫的伺服器端與用戶端應用程式邏輯。
  • 將 UI 轉譯為 HTML 和 CSS 以支援寬瀏覽器,包括行動裝置瀏覽器。

Blazor 架構支援的案例:

  • 可重複使用的 UI 元件 (Razor 元件)
  • 用戶端路由
  • 元件配置
  • 對相依性插入的支援
  • 表單和驗證
  • 在 Razor 類別庫中提供 Razor 元件
  • JavaScript Interop

如需詳細資訊,請參閱 ASP.NET Core Blazor

Blazor Server

Blazor 會將元件轉譯邏輯與套用 UI 更新的方式分隔。 Blazor Server 提供在 ASP.NET Core 應用程式中將 Razor 元件裝載在伺服器上的支援。 UI 更新會透過 SignalR 連線進行處理。 ASP.NET Core 3.0 支援 Blazor Server。

Blazor WebAssembly (預覽版)

Blazor 應用程式也可以使用 WebAssembly 型 .NET 執行階段直接在瀏覽器中執行。 Blazor WebAssembly 處於預覽階段,ASP.NET Core 3.0 對其 提供支援。 ASP.NET Core 的未來版本將會支援 Blazor WebAssembly。

Razor 元件

Blazor 應用程式是由元件建置的。 元件是使用者介面 (UI) 的獨立式區塊,例如頁面、對話方塊或表單。 元件是定義 UI 轉譯邏輯和用戶端事件處理常式的一般 .NET 類別。 無需 JavaScript 即可建立豐富的互動式 Web 應用程式。

Blazor 中的元件通常會使用 Razor 語法撰寫,該語法是 HTML 和 C# 的自然混合語法。 Razor 元件與 Razor Pages 和 MVC 檢視類似,因為它們都使用 Razor。 不同於以要求-回應模型為基礎的頁面和檢視,元件是專門用來處理 UI 組合。

gRPC

gRPC

  • 這是熱門的高效能 RPC (遠端程序呼叫) 架構。

  • 提供固定且合約優先的 API 開發方法。

  • 使用如下新式技術:

    • 用於傳輸的 HTTP/2。
    • 作為介面描述語言的通訊協定緩衝區。
    • 二進位序列化格式。
  • 提供如下功能:

    • 驗證
    • 雙向串流和流程控制。
    • 取消和逾時。

ASP.NET Core 3.0 中的 gRPC 功能包括:

  • Grpc.AspNetCore:用於裝載 gRPC 服務的 ASP.NET Core 架構。 ASP.NET Core 上的 gRPC 與標準 ASP.NET Core 功能 (如記錄、相依性插入 (DI)、驗證和授權) 整合。
  • Grpc.Net.Client:.NET Core 的 gRPC 用戶端,其以熟悉的 HttpClient 作為建置基礎。
  • Grpc.Net.ClientFactory:gRPC 用戶端與 HttpClientFactory 的整合。

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

SignalR

如需移轉指示,請參閱更新 SignalR 程式碼。 SignalR 現在會使用 System.Text.Json 來序列化/還原序列化 JSON 訊息。 如需還原 Newtonsoft.Json 型序列化程式的指示,請參閱切換至 Newtonsoft.Json

在 SignalR 的 JavaScript 和 .NET 用戶端中,已新增自動重新連線的支援。 根據預設,用戶端會嘗試立即重新連線,並在必要時於 2、10 和 30 秒之後重試。 如果用戶端成功重新連線,就會收到新的連線識別碼。 選擇加入自動重新連線:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .withAutomaticReconnect()
    .build();

透過傳遞以毫秒為基礎的持續時間陣列,即可指定重新連線間隔:

.withAutomaticReconnect([0, 3000, 5000, 10000, 15000, 30000])
//.withAutomaticReconnect([0, 2000, 10000, 30000]) The default intervals.

您可以傳入自訂實作,以完全控制重新連線間隔。

如果重新連線在上次重新連線間隔之後失敗:

  • 用戶端會將連線視為離線。
  • 用戶端會停止嘗試重新連線。

在重新連線嘗試期間,更新應用程式 UI 以通知使用者正在嘗試重新連線。

為了在連線中斷時提供 UI 意見反應,SignalR 用戶端 API 已擴展成包含下列事件處理常式:

  • onreconnecting:讓開發人員有機會停用 UI,或讓使用者知道應用程式已離線。
  • onreconnected:讓開發人員有機會在重新建立連線之後更新 UI。

下列程式碼會使用 onreconnecting 在嘗試連線時更新 UI:

connection.onreconnecting((error) => {
    const status = `Connection lost due to error "${error}". Reconnecting.`;
    document.getElementById("messageInput").disabled = true;
    document.getElementById("sendButton").disabled = true;
    document.getElementById("connectionStatus").innerText = status;
});

下列程式碼會使用 onreconnected 在連線時更新 UI:

connection.onreconnected((connectionId) => {
    const status = `Connection reestablished. Connected.`;
    document.getElementById("messageInput").disabled = false;
    document.getElementById("sendButton").disabled = false;
    document.getElementById("connectionStatus").innerText = status;
});

當中樞方法需要授權時,SignalR 3.0 和更新版本可提供自訂資源給授權處理常式。 資源是 HubInvocationContext 的執行個體。 HubInvocationContext 包含:

  • HubCallerContext
  • 正在叫用的中樞方法名稱。
  • 中樞方法的引數。

請考慮下列允許透過 Azure Active Directory 進行多個組織登入的聊天室應用程式範例。 擁有 Microsoft 帳戶的任何人都可以登入聊天,但只有擁有組織的成員才能禁止使用者或檢視使用者的聊天歷程記錄。 應用程式可能會限制特定使用者的某些功能。

public class DomainRestrictedRequirement :
    AuthorizationHandler<DomainRestrictedRequirement, HubInvocationContext>,
    IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
        DomainRestrictedRequirement requirement,
        HubInvocationContext resource)
    {
        if (context.User?.Identity?.Name == null)
        {
            return Task.CompletedTask;
        }

        if (IsUserAllowedToDoThis(resource.HubMethodName, context.User.Identity.Name))
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }

    private bool IsUserAllowedToDoThis(string hubMethodName, string currentUsername)
    {
        if (hubMethodName.Equals("banUser", StringComparison.OrdinalIgnoreCase))
        {
            return currentUsername.Equals("bob42@jabbr.net", StringComparison.OrdinalIgnoreCase);
        }

        return currentUsername.EndsWith("@jabbr.net", StringComparison.OrdinalIgnoreCase));
    }
}

在上述程式碼中,DomainRestrictedRequirement 會作為自訂 IAuthorizationRequirement。 由於正在傳入 HubInvocationContext 資源參數,因此內部邏輯可以:

  • 檢查在其中呼叫中樞的內容。
  • 決定允許使用者執行個別的中樞方法。

您可以使用程式碼在執行階段檢查的原則名稱來標記個別的中樞方法。 當用戶端嘗試呼叫個別的中樞方法時,DomainRestrictedRequirement 處理常式會執行並控制對方法的存取。 根據 DomainRestrictedRequirement 控制存取的方式:

  • 所有登入的使用者都可以呼叫 SendMessage 方法。
  • 只有使用 @jabbr.net 電子郵件地址登入的使用者才能檢視使用者的歷程記錄。
  • 只有 bob42@jabbr.net 才能禁止使用者使用聊天室。
[Authorize]
public class ChatHub : Hub
{
    public void SendMessage(string message)
    {
    }

    [Authorize("DomainRestricted")]
    public void BanUser(string username)
    {
    }

    [Authorize("DomainRestricted")]
    public void ViewUserHistory(string username)
    {
    }
}

建立 DomainRestricted 原則可能涉及:

  • Startup.cs 中新增原則。
  • 提供自訂 DomainRestrictedRequirement 需求作為參數。
  • 向授權中介軟體註冊 DomainRestricted
services
    .AddAuthorization(options =>
    {
        options.AddPolicy("DomainRestricted", policy =>
        {
            policy.Requirements.Add(new DomainRestrictedRequirement());
        });
    });

SignalR 中樞使用端點路由。 先前已明確完成 SignalR 中樞連線:

app.UseSignalR(routes =>
{
    routes.MapHub<ChatHub>("hubs/chat");
});

在舊版中,開發人員需要在各種位置連接控制器、Razor 頁面和中樞。 明確連線會產生一系列幾乎完全相同的路由區段:

app.UseSignalR(routes =>
{
    routes.MapHub<ChatHub>("hubs/chat");
});

app.UseRouting(routes =>
{
    routes.MapRazorPages();
});

SignalR 3.0 中樞可以透過端點路由進行路由傳送。 使用端點路由時,通常所有路由都可以在 UseRouting 中設定:

app.UseRouting(routes =>
{
    routes.MapRazorPages();
    routes.MapHub<ChatHub>("hubs/chat");
});

ASP.NET Core 3.0 SignalR 已新增:

用戶端對伺服器串流。 使用用戶端對伺服器串流,伺服器端方法可以採用 IAsyncEnumerable<T>ChannelReader<T> 的執行個體。 在下列 C# 範例中,中樞上的 UploadStream 方法會從用戶端收到字串串流:

public async Task UploadStream(IAsyncEnumerable<string> stream)
{
    await foreach (var item in stream)
    {
        // process content
    }
}

.NET 用戶端應用程式可以將 IAsyncEnumerable<T>ChannelReader<T> 執行個體作為上述 UploadStream 中樞方法的 stream 引數傳遞。

for 迴圈完成且本機函式結束之後,就會傳送串流完成:

async IAsyncEnumerable<string> clientStreamData()
{
    for (var i = 0; i < 5; i++)
    {
        var data = await FetchSomeData();
        yield return data;
    }
}

await connection.SendAsync("UploadStream", clientStreamData());

JavaScript 用戶端應用程式會針對上述 UploadStream 中樞方法的 stream 引數使用 SignalRSubject (或 RxJS 主題)。

let subject = new signalR.Subject();
await connection.send("StartStream", "MyAsciiArtStream", subject);

在擷取字串並準備好將其傳送至伺服器時,JavaScript 程式碼可以使用 subject.next 方法來處理這些字串。

subject.next("example");
subject.complete();

使用上述兩個程式碼片段之類的程式碼,便可建立即時串流體驗。

新的 JSON 序列化

ASP.NET Core 3.0 現在預設會針對 JSON 序列化使用 System.Text.Json

  • 以非同步方式讀取和寫入 JSON。
  • 已針對 UTF-8 文字進行最佳化。
  • 效能通常高於 Newtonsoft.Json

若要將 Json.NET 新增至 ASP.NET Core 3.0,請參閱新增 Newtonsoft.Json 型 JSON 格式支援

新的 Razor 指示詞

下列清單包含新的 Razor 指示詞:

  • @attribute@attribute 指示詞會將指定屬性套用至所產生頁面或檢視的類別。 例如: @attribute [Authorize]
  • @implements@implements 指示詞會針對產生的類別實作介面。 例如: @implements IDisposable

IdentityServer4 支援 Web API 和 SPA 的驗證和授權

ASP.NET Core 3.0 會使用 Web API 授權的支援,在單頁應用程式 (SPA) 中提供驗證。 用於驗證和儲存使用者的 ASP.NET Core Identity 與用於實作 OpenID Connect 的 IdentityServer4 相結合。

IdentityServer4 是適用於 ASP.NET Core 3.0 的 OpenID Connect 和 OAuth 2.0 架構。 其可啟用下列安全性功能:

  • 驗證即服務 (AaaS)
  • 多個應用程式類型的單一登入/登出 (SSO)
  • API 的存取控制
  • Federation Gateway

如需詳細資訊,請參閱 IdentityServer4 文件SPA 的驗證和授權

憑證和 Kerberos 驗證

憑證驗證需要:

  • 設定伺服器以接受憑證。
  • Startup.Configure 中新增驗證中介軟體。
  • Startup.ConfigureServices 中新增憑證驗證服務。
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
            .AddCertificate();
    // Other service configuration removed.
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    // Other app configuration removed.
}

憑證驗證的選項包括能夠:

  • 接受自我簽署憑證。
  • 檢查憑證撤銷。
  • 檢查所提供的憑證是否具有正確的使用方式旗標。

預設使用者主體是透過憑證屬性建構而成。 使用者主體包含可補充或取代主體的事件。 如需詳細資訊,請參閱在 ASP.NET Core 中設定憑證驗證

Windows 驗證已擴展至 Linux 和 macOS。 在舊版中,Windows 驗證僅限於 IISHTTP.sys。 在 ASP.NET Core 3.0 中,Kestrel 能夠針對已加入 Windows 網域的主機,在 Linux 和 macOS 上使用 Negotiate、KerberosWindows 上的 NTLMMicrosoft.AspNetCore.Authentication.Negotiate NuGet 套件提供這些驗證配置的 Kestrel 支援。 如同其他驗證服務一樣,請設定整個驗證應用程式,然後設定服務:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate();
    // Other service configuration removed.
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    // Other app configuration removed.
}

主機需求:

  • Windows 主機必須將服務主體名稱 (SPN) 新增至裝載應用程式的使用者帳戶。
  • Linux 和 macOS 電腦必須加入網域。
    • 必須為 Web 流程建立 SPN。
    • 必須在主機電腦上產生並設定金鑰表檔案

如需詳細資訊,請參閱在 ASP.NET Core 中設定 Windows 驗證

範本變更

Web UI 範本 (Razor 頁面、具有控制器和檢視的 MVC) 已移除下列項目:

Angular 範本已更新為使用 Angular 8。

根據預設,Razor 類別庫 (RCL) 範本預設為 Razor 元件開發。 Visual Studio 中的新範本選項為頁面和檢視提供範本支援。 在命令殼層從範本建立 RCL 時,請傳遞 --support-pages-and-views 選項 (dotnet new razorclasslib --support-pages-and-views)。

一般主機

ASP.NET Core 3.0 範本會使用 ASP.NET Core 中的 .NET 一般主機。 舊版則使用 WebHostBuilder。 使用 .NET Core 一般主機 (HostBuilder) 可提供 ASP.NET Core 應用程式與非 Web 特定伺服器案例的更好整合。 如需詳細資訊,請參閱 HostBuilder 取代 WebHostBuilder

主機組態

在發行 ASP.NET Core 3.0 之前,會載入前置詞為 ASPNETCORE_ 的環境變數,以供 Web 主機的主機組態使用。 在 3.0 中,可使用 AddEnvironmentVariables 為含有 CreateDefaultBuilder 的主機組態載入字首為 DOTNET_ 的環境變數。

Startup 建構函式插入的變更

一般主機只支援下列類型的 Startup 建構函式插入:

所有服務仍然可以直接插入為 Startup.Configure 方法的引數。 如需詳細資訊,請參閱一般主機限制 Startup 建構函式插入 (aspnet/Announcements #353)

Kestrel

  • 已更新 Kestrel 組態以移轉至一般主機。 在 3.0 中,Kestrel 會在 ConfigureWebHostDefaults 所提供的 Web 主機建立器上設定。
  • 連線配接器已從 Kestrel 中移除並取代為連線中介軟體,該中介軟體類似於 ASP.NET Core 管線中的 HTTP 中介軟體,但適用於較低層級的連線。
  • Kestrel 傳輸層已公開為 Connections.Abstractions 中的公用介面。
  • 透過將尾端標頭移至新的集合,可解決標頭與結尾之間的模糊情況。
  • 同步 I/O API (例如 HttpRequest.Body.Read) 是執行緒不足 (導致應用程式當機) 的常見原因。 在 3.0 中,預設會停用 AllowSynchronousIO

如需詳細資訊,請參閱從 ASP.NET Core 2.2 移轉到 3.0

預設啟用 HTTP/2

預設在 Kestrel 中針對 HTTPS 端點啟用 HTTP/2。 當作業系統支援 HTTP/2 時,就會對 IIS 或 HTTP.sys 啟用 HTTP/2 支援。

要求時的 EventCounter

裝載的 EventSource Microsoft.AspNetCore.Hosting 會發出下列與傳入要求相關的新 EventCounter 類型:

  • requests-per-second
  • total-requests
  • current-requests
  • failed-requests

端點路由

已增強端點路由,其可讓架構 (例如 MVC) 搭配中介軟體順利運作:

  • 中介軟體和端點的順序可在 Startup.Configure 的要求處理管線中設定。
  • 端點和中介軟體與其他 ASP.NET Core 型技術 (例如,健康情況檢查) 完美組合。
  • 端點可以在中介軟體和 MVC 中實作原則,例如 CORS 或授權。
  • 篩選和屬性可以放置在控制器的方法上。

如需詳細資訊,請參閱 ASP.NET Core 中的路線規劃

健康情況檢查

健康情況檢查會搭配一般主機使用端點路由。 在 Startup.Configure 中,使用端點 URL 或相對路徑在端點建立器上呼叫 MapHealthChecks

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

健康情況檢查端點可以:

  • 指定一或多個允許的主機/連接埠。
  • 需要授權。
  • 需要 CORS。

如需詳細資訊,請參閱下列文章:

HttpContext 上的管道

現在可以使用 System.IO.Pipelines API 讀取要求本文並寫入回應本文。 HttpRequest.BodyReader 屬性提供可用來讀取要求本文的 PipeReaderHttpResponse.BodyWriter 屬性提供可用來寫入回應本文的 PipeWriterHttpRequest.BodyReaderHttpRequest.Body 串流的類比。 HttpResponse.BodyWriterHttpResponse.Body 串流的類比。

已改善 IIS 中的錯誤報告

在 IIS 中裝載 ASP.NET Core 應用程式時發生的啟動錯誤,現在會產生更豐富的診斷資料。 在適用情況下,這些錯誤會連同堆疊追蹤報告給 Windows 事件記錄檔。 此外,所有警告、錯誤和未處理的例外狀況都會記錄到 Windows 事件記錄檔。

背景工作服務和背景工作 SDK

.NET Core 3.0 引進了新的背景工作服務應用程式範本。 此範本提供在 .NET Core 中撰寫長時間執行服務的起點。

如需詳細資訊,請參閱

轉送標頭中介軟體改善

在舊版的 ASP.NET Core 中,當部署至 Azure Linux 或 IIS 以外的任何反向 Proxy 後方時,呼叫 UseHstsUseHttpsRedirection 會發生問題。 轉送 Linux 和非 IIS 反向 Proxy 的配置中記載了舊版的修正內容。

ASP.NET Core 3.0 中已修正此案例。 當 ASPNETCORE_FORWARDEDHEADERS_ENABLED 環境變數設定為 true 時,主機會啟用轉送標頭中介軟體ASPNETCORE_FORWARDEDHEADERS_ENABLED 會在容器映像中設定為 true

效能改善

ASP.NET Core 3.0 包含多項改善,可降低記憶體使用量並提高輸送量:

  • 降低針對範圍服務使用內建相依性插入容器時的記憶體使用量。
  • 減少整個架構的配置,包括中介軟體案例和路由。
  • 降低 WebSocket 連線的記憶體使用量。
  • 降低 HTTPS 連線的記憶體使用量並提高其輸送量。
  • 新增已最佳化且完全非同步的 JSON 序列化程式。
  • 降低表單剖析的記憶體使用量並提高其輸送量。

ASP.NET Core 3.0 僅在 .NET Core 3.0 上執行

從 ASP.NET Core 3.0 開始,不再支援 .NET Framework 作為目標架構。 以 .NET Framework 為目標的專案可以使用 .NET Core 2.1 LTS 版本,以完全支援的方式繼續執行。 超過 .NET Core 2.1 的三年 LTS 期間之後,將無限期支援大部分的 ASP.NET Core 2.1.x 相關套件。

如需移轉資訊,請參閱將程式碼從 .NET Framework 移植到 .NET Core

使用 ASP.NET Core 共用架構

包含在 Microsoft.AspNetCore.App 中繼套件中的 ASP.NET Core 3.0 共用架構,不再需要專案檔中有一個明確的 <PackageReference /> 元素。 在專案檔中使用 Microsoft.NET.Sdk.Web SDK 時,將會自動參考共用架構:

<Project Sdk="Microsoft.NET.Sdk.Web">

從 ASP.NET Core 共用架構中移除的組件

從 ASP.NET Core 3.0 共用架構移除的組件中最值得注意的是:

如需從共用架構移除之組件的完整清單,請參閱從 Microsoft.AspNetCore.App 3.0 中移除的組件。 如需此變更動機的詳細資訊,請參閱 3.0 中 Microsoft.AspNetCore.App 的中斷性變更搶先看 ASP.NET Core 3.0 的變更