[翻譯] ASP.NET Core 3.0 的新增功能

ASP.NET Core 3.0 的新增功能

全文翻譯自微軟官方文檔英文版 What's new in ASP.NET Core 3.0javascript

本文重點介紹了 ASP.NET Core 3.0 中最重要的更改,並提供相關文檔的鏈接。html

[TOC]java

Blazor

Blazor 是 ASP.NET Core 中的一個新的框架,用於使用 .NET 構建交互式的客戶端 Web UI:linux

  • 使用 C# 而不是 JavaScript 建立豐富的交互式 UI。
  • 共享用 .NET 編寫的服務器端和客戶端應用程序邏輯。
  • 將 UI 渲染爲 HTML 和 CSS,以提供普遍的瀏覽器支持,包括移動瀏覽器。

Blazor 框架支持的場景:git

  • 可重用的 UI 組件(Razor 組件)
  • 客戶端路由
  • 組件佈局
  • 對依賴注入的支持
  • 表單與驗證
  • 使用 Razor 類庫構建組件庫
  • JavaScript 互操做

有關更多信息,請參閱:ASP.NET Core 中的 Blazor 簡介github

Blazor Server

Blazor 將組件渲染邏輯與 UI 更新的邏輯進行了解耦。Blazor Server 支持在服務器上的 ASP.NET Core 應用程序中承載 Razor 組件。UI 的更新經過一個 SignalR 鏈接進行處理。Blazor Server 在 ASP.NET Core 3.0 中受支持。web

Blazor WebAssembly (預覽)

Blazor 應用程序也可使用基於 WebAssembly 的 .NET 運行時直接在瀏覽器中運行。Blazor WebAssembly 在 ASP.NET Core 3.0 中處於預覽狀態,且不受支持。將來的 ASP.NET Core 版本將支持 Blazor WebAssembly。json

Razor 組件

Blazor 應用程序是由組件 (components) 構建而成的。組件是自包含的用戶界面元素,例如頁面、對話框或者表單等。組件是普通的 .NET 類,用於定義 UI 呈現邏輯和客戶端事件處理程序。您能夠建立沒有 JavaScript 的富交互式 Web 應用程序。windows

Blazor 中的組件一般使用 Razor 語法編寫,它是 HTML 和 C# 的天然融合。Razor 組件與 Razor Pages(頁面)和 MVC 視圖 (view) 類似,由於它們都使用 Razor。與基於「請求-響應」模型的頁面與視圖不一樣,組件專門用於處理 UI 合成。api

gRPC

gRPC

  • 是一種流行的高性能 RPC(遠程過程調用)框架。
  • 爲 API 開發提供了一種「契約優先「的方式。
  • 使用各類現代的技術,例如:
    • 經過 HTTP/2 傳輸
    • 使用 Protocol Buffers 做爲接口描述語言
    • 二進制序列化格式
  • 提供如下功能:
    • 身份驗證
    • 雙向的數據流與流程控制
    • 取消與超時

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

  • Grpc.AspNetCore — 一個用於承載 gRPC 服務的 ASP.NET Core 框架。ASP.NET Core 上的 gRPC 可以與日誌記錄、依賴注入 (DI) 身份驗證和受權等標準的 ASP.NET Core 功能集成在一塊兒。
  • Grpc.Net.Client — 一個面向 .NET Core,構建在 HttpClient 上的 gRPC 客戶端。
  • Grpc.Net.ClientFactory — 用於將 gRPC 客戶端與 HttpClientFactory 集成。

有關更多信息,參見:ASP.NET Core 上 gRPC 的簡介

SignalR

請參見更新 Signal 代碼以獲取遷移說明。SignalR 如今使用 System.Text.Json 來序列化/反序列化 JSON 消息。有關還原爲基於 Newtonsoft.Json 的序列化程序的說明,請參閱切換到 Newtonsoft.Json

在 SignalR 的 JavaScript 和 .NET 客戶端中,添加了對自動從新鏈接的支持。默認狀況下,客戶端嘗試自動從新鏈接,並在 2, 10 和 30 秒後(若有必要)重試。若是客戶端成功從新鏈接,它將受到一個新的鏈接 ID。自動從新鏈接是選擇性加入的:

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

能夠經過傳遞基於毫秒的持續時間數組來指定從新鏈接間隔:

.withAutomaticReconnect([0, 3000, 5000, 10000, 15000, 30000])
//.withAutomaticReconnect([0, 2000, 10000, 30000]) 默認時間間隔

能夠傳入自定義實現以徹底控制從新鏈接間隔。

若是在上次從新鏈接間隔以後從新鏈接失敗,則:

  • 客戶端認爲鏈接已離線。
  • 客戶端中止嘗試從新鏈接。

爲了在鏈接中斷時提供 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;
});

當 hub 方法須要受權時,SignalR 3.0 及更高版本爲受權處理程序提供自定義資源。該資源是 HubInvocationContext 的實例。HubInvocationContext 包括:

  • HubCallerContext
  • 正在調用的 hub 方法的名稱。
  • hub 方法的參數。

考慮如下聊天室應用程序示例,該應用程序容許經過 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 資源,所以內部邏輯能夠:

  • 檢查正在調用 hub 的上下文。
  • 決定是否容許用戶執行特定的 hub 方法。

可使用策略名稱來修飾各個 hub 方法,代碼會在運行時進行檢查。當客戶端嘗試調用各個 hub 方法時,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 hub 使用終結點路由。SignalR hub 鏈接先前已顯式地完成:

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

在之前的版本中,開發人員須要在各個不一樣的位置啓用控制器、Razor 頁面和 SignalR hub。顯式的鏈接致使一系列幾乎相同的路由片斷:

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

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

SignalR 3.0 hub 能夠經過終結點路由進行路由。使用終結點路由,一般能夠在 UseRouting 中配置全部的路由:

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

ASP.NET Core 3.0 SignalR 添加了:

客戶端到服務器的流。經過客戶端到服務器的流傳輸,服務器端方法能夠採用 IAsyncEnumerable<T> 或者 ChannelReader<T> 的實例。在如下 C# 實例中,hub 上的 UploadStream 方法將從客戶端接收字符串流:

public async Task UploadStream(IAsyncEnumerable<string> stream)
{
    await foreach (var item in stream)
    {
        // 處理流中的內容
    }
}

.NET 客戶端應用程序能夠將一個 IAsyncEnumerable<T> 或者 ChannelReader<T> 的實例做爲上述 UploadStream hub 方法的 stream 參數進行傳遞。

for 循環完成,且本地函數退出以後,將流完成發送(After the for loop has completed and the local function exits, the stream completion is sent):

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

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

JavaScript 客戶端應用將 SignalR Subject (或者一個 RxJS Subject) 用於上述 UploadStream hub 方法的 stream 參數。

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 使用 System.Text.Json 進行 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

證書與 Kerberos 身份驗證

證書身份驗證要求:

  • 配置服務器以接收證書。
  • Startup.Configure 中添加身份驗證中間件。
  • Startup.ConfigureServices 中添加證書身份驗證服務。
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
            .AddCertificate();
    // 其餘服務配置已移除。
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    // 其餘應用配置已移除。
}

證書身份驗證的選項 (Options) 提供如下功能:

  • 接受自簽名證書。
  • 檢查證書吊銷。
  • 檢查提供的證書是否具備正確的使用標誌。

默認的用戶主體 (user principal) 是根據證書屬性構建的。用戶主體包含一個事件。經過相應該事件,能夠補充或者替換該主體。有關更多信息,請參見在 ASP.NET Core 中配置證書身份驗證

Windows 身份驗證 已擴展到了 Linux 和 macOS 上。在之前的版本中,Windows 身份驗證僅限於 IISHttpSys。在 ASP.NET Core 3.0 中,Kestrel 可以在 Windows, Linux 和 macOS 上爲加入了 Windows 域的主機使用 Negotiate(協商), KerberosNTLM。Kestrel 對這些身份驗證架構的支持由 Microsoft.AspNetCore.Authentication.Negotiate NuGet 包提供。與其餘身份驗證服務同樣,在用用程序範圍內配置身份驗證,而後配置服務:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate();
    // 其餘服務配置已移除。
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    // 其餘應用配置已移除。
}

主機要求:

  • Windows 主機必須將服務主體名稱 (SPN) 添加到承載該應用程序的用戶帳戶中。
  • Linux 和 macOS 主機必須加入域。
    • 必須爲 Web 進程建立 SPN。
    • 必須在主機上生成和配置密鑰表文件

有關更多信息,請參見在 ASP.NET Core 中配置 Windows 身份驗證

模板變動

Web UI 模板(Razor Pages, 帶有控制器和視圖的 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 模板使用 .NET 通用主機。之前的版本使用 WebHostBuilder。使用 .NET Core 通用主機(HostBuilder),能夠更好地將 ASP.NET Core 應用程序與其餘非特定與 Web 的服務器方案集成。有關更多信息,請參見 HostBuilder 替換 WebHostBuilder

主機配置

在發佈 ASP.NET Core 3.0 以前,帶有 ASPNETCORE_ 前綴的環境變量會被加載,用於 Web 主機的主機配置。在 3.0 中,AddEvironmentVariables 用於加載帶有 DOTNET_ 之前追的環境變量,以使用 CreateDefaultBuilder 進行主機配置。

Startup 構造函數注入的更改

通用主機僅支持一下類型的 Startup 構造函數注入:

仍然能夠將全部服務以參數的形式直接注入 Startup.Configure 方法,參見 通用主機限制 Startup 構造函數注入 (aspnet/Announcements #353).

Kestrel

  • 爲了遷移到通用主機,Kestrel 配置已更新。在 3.0 中,Kestrel 在 ConfigureWebHostDefaults 提供的 Web 主機構建器 (host builder) 上進行配置。
  • 鏈接適配器 (Connection Adapter) 已從 Kestrel 中刪除,並由鏈接中間件代替 (Connection Middleware)。該中間件相似於 ASP.NET Core 管道中的 HTTP 中間件,但用於較低級別的鏈接。
  • Kestrel 傳輸層已在 Connections.Abstractions 中做爲公共接口公開。
  • 標頭 (header) 和尾部 (trailer) 之間的歧義已經過將尾部標頭 (trailing header) 移動到新的集合來解決。
  • 同步 IO API(例如 HttpRequest.Body.Read)是引發線程飢餓進而致使程序崩潰的常見緣由。在 3.0 中,默認狀況下 AllowSynchronousIO 被禁用。

有關更多信息,請參見Kestrel - 從 ASP.NET Core 2.2 遷移到 3.0

默認啓用 HTTP/2

默認狀況下,Kestrel 中爲 HTTPS 端點啓用了 HTTP/2。當操做系統支持時,對 IIS 或者 HTTP.sys 的 HTTP/2 的支持將被啓用。

請求計數器

Hosting EventSource (Microsoft.AspNetCore.Hosting) 發出與傳入請求有關的如下 EventCounter:

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

終結點路由

終結點路由獲得了加強,該路由使各類框架(例如 MVC)能夠與中間件更好地協同工做:

  • 中間件和終結點的順序能夠在 Startup.Configure 的請求處理管道中進行配置。
  • 終結點和中間件與其餘基於 ASP.NET Core 的技術(例如運行情況檢查)進行良好的編排。
  • 終結點能夠在中間件和 MVC 中實現各類策略,例如 CORS 或者受權等。
  • 過濾器和特性 (attribute) 能夠被放置在控制器的方法上。

有關更多信息,請參見 ASP.NET Core 中的路由

運行情況檢查

運行情況檢查經過通用主機使用終結點路由。在 Startup.Configure 中,使用終結點 URL 或者相對路徑,在終結點構建器上調用 MapHealthChecks

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

運行情況檢查終結點能夠:

  • 指定一個或多個容許的主機/端口。
  • 要求受權。
  • 要求 CORS。

有關更多信息,請參見如下文章:

HttpContext 上的管道

如今可使用 System.IO.Pipelines API 讀取請求正文並寫入響應正文。HttpRequest.BodyReader 屬性提供了一個 PipeReader,能夠用於讀取請求正文;HttpResponse.BodyWriter 屬性提供了一個 PipeWriter,能夠用於寫入響應正文。HttpRequest.BodyReaderHttpRequest.Body 流的類似物; HttpResponse.BodyWriterHttpResponse.Body 流的類似物。

IIS 中改進了的錯誤報告

如今,在 IIS 中託管 ASP.NET Core 應用程序時的啓動錯誤會生成更豐富的診斷數據。這些錯誤會在適用的狀況下使用堆棧跟蹤,報告給 Windows 事件日誌。此外,全部的警告、錯誤和未處理的異常,都會記錄到 Windows 事件日誌中。

服務角色服務和輔助角色 SDK

.NET Core 3.0 引入了新的輔助角色服務 (Worker Service) 應用模板。該模板是在 .NET Core 中編寫長時間運行的服務的起點。

有關更多信息,請參見:

Forwarded 標頭中間件的改進

在早期版本的 ASP.NET Core 中,應用在部署到 Azure Linux 或者除 IIS 以外的任何反向代理以後,調用 UseHstsUseHttpsRedirection 都是有問題的。轉發 Linux 和非 IIS 反向代理的方案中介紹了之前版本的修復方式。

此場景已在 ASP.NET Core 3.0 中修復。當 ASPNETCORE_FORWARDEDHEADERS_ENABLED 環境變量設置爲 true 時,主機將啓用 Forwarded 標頭中間件。在 ASP.NET Core 的容器鏡像中,ASPNETCORE_FORWARDEDHEADERS_ENABLED 已被設置爲 true

性能提高

ASP.NET Core 3.0 包括許多改進,能夠減小內存使用並提升吞吐量:

  • 在將內置的依賴注入容器用於 scoped 服務時,減小內存的使用量。
  • 減小整個框架的內存分配,包括中間件的各種場景和路由。
  • 減小 WebSocket 鏈接的內存使用量。
  • 減小 HTTPS 鏈接的內存使用量,並提升吞吐量。
  • 新的、通過優化的、徹底異步的 JSON 序列化器。
  • 減小表單 (form) 解析的內存使用量,並提升吞吐量。

ASP.NET Core 3.0 僅可在 .NET Core 3.0 上運行

從 ASP.NET Core 3.0開始,.NET Framework 再也不是受支持的目標框架。以 .NET Framework 爲目標的項目能夠繼續經過使用 .NET Core 2.1 LTS 版本在徹底受支持的狀態下運行。絕大多數與 ASP.NET Core 2.1.x 相關的軟件包,都將在 .NET Core 2.1 的三年長期支持期內得到支持。(Most ASP.NET Core 2.1.x related packages will be supported indefinitely, beyond the 3 year LTS period for .NET Core 2.1.)

有關遷移的更多信息,請參見 將代碼從 .NET Framework 移植到 .NET Core

使用 ASP.NET Core 共享框架

Microsoft.AspNetCore.App 元包中包含的 ASP.NET Core 3.0 共享框架 (shared framework) 再也不須要項目文件中的顯式 <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 中移除的程序集。有關進行此修改的動機,更多信息請參閱Microsoft.AspNetCore.App 在 3.0 中的破壞性變動ASP.NET Core 3.0 中的更改初探

原文出處:https://www.cnblogs.com/vxchin/p/whats-new-in-asp-net-core-3-0.html

相關文章
相關標籤/搜索