全文翻译自微软官方文档英文版 What's new in ASP.NET Core 3.0javascript
本文重点介绍了 ASP.NET Core 3.0 中最重要的更改,并提供相关文档的链接。html
[TOC]java
Blazor 是 ASP.NET Core 中的一个新的框架,用于使用 .NET 构建交互式的客户端 Web UI:linux
Blazor 框架支持的场景:git
有关更多信息,请参阅:ASP.NET Core 中的 Blazor 简介。github
Blazor 将组件渲染逻辑与 UI 更新的逻辑进行了解耦。Blazor Server 支持在服务器上的 ASP.NET Core 应用程序中承载 Razor 组件。UI 的更新经过一个 SignalR 链接进行处理。Blazor Server 在 ASP.NET Core 3.0 中受支持。web
Blazor 应用程序也可使用基于 WebAssembly 的 .NET 运行时直接在浏览器中运行。Blazor WebAssembly 在 ASP.NET Core 3.0 中处于预览状态,且不受支持。将来的 ASP.NET Core 版本将支持 Blazor WebAssembly。json
Blazor 应用程序是由组件 (components) 构建而成的。组件是自包含的用户界面元素,例如页面、对话框或者表单等。组件是普通的 .NET 类,用于定义 UI 呈现逻辑和客户端事件处理程序。您能够建立没有 JavaScript 的富交互式 Web 应用程序。windows
Blazor 中的组件一般使用 Razor 语法编写,它是 HTML 和 C# 的天然融合。Razor 组件与 Razor Pages(页面)和 MVC 视图 (view) 类似,由于它们都使用 Razor。与基于“请求-响应”模型的页面与视图不一样,组件专门用于处理 UI 合成。api
gRPC:
ASP.NET Core 3.0 中的 gRPC 功能包括:
HttpClient
上的 gRPC 客户端。HttpClientFactory
集成。有关更多信息,参见:ASP.NET Core 上 gRPC 的简介
请参见更新 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
考虑如下聊天室应用程序示例,该应用程序容许经过 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 方法时,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
策略可能涉及:
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();
使用相似前面两个代码段的代码,能够建立实时流式传输体验。
如今默认状况下,ASP.NET Core 3.0 使用 System.Text.Json 进行 JSON 序列化:
Newtonsoft.Json
具备更高的性能。要将 Json.NET 添加到 ASP.NET Core 3.0 请参阅添加基于 Newtonsoft.Json 的 JSON 格式支持。
如下列表包含了新的 Razor 指令:
@attribute
指令将给定属性应用于生成页面或者视图的类。例如:@attribute [Authorize]
。@implements
指令为生成的类实现一个接口。例如:@implements IDisposable
。证书身份验证要求:
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 身份验证仅限于 IIS 和 HttpSys。在 ASP.NET Core 3.0 中,Kestrel 可以在 Windows, Linux 和 macOS 上为加入了 Windows 域的主机使用 Negotiate(协商), Kerberos 和 NTLM。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(); // 其余应用配置已移除。 }
主机要求:
有关更多信息,请参见在 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
构造函数注入:
IWebHostEnvironment
仍然能够将全部服务以参数的形式直接注入 Startup.Configure
方法,参见 通用主机限制 Startup 构造函数注入 (aspnet/Announcements #353).
ConfigureWebHostDefaults
提供的 Web 主机构建器 (host builder) 上进行配置。Connections.Abstractions
中做为公共接口公开。HttpRequest.Body.Read
)是引发线程饥饿进而致使程序崩溃的常见缘由。在 3.0 中,默认状况下 AllowSynchronousIO
被禁用。有关更多信息,请参见Kestrel - 从 ASP.NET Core 2.2 迁移到 3.0。
默认状况下,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 中的路由。
运行情况检查经过通用主机使用终结点路由。在 Startup.Configure
中,使用终结点 URL 或者相对路径,在终结点构建器上调用 MapHealthChecks
:
app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); });
运行情况检查终结点能够:
有关更多信息,请参见如下文章:
如今可使用 System.IO.Pipelines API 读取请求正文并写入响应正文。HttpRequest.BodyReader
属性提供了一个 PipeReader,能够用于读取请求正文;HttpResponse.BodyWriter
属性提供了一个 PipeWriter,能够用于写入响应正文。HttpRequest.BodyReader
是 HttpRequest.Body
流的类似物; HttpResponse.BodyWriter
是 HttpResponse.Body
流的类似物。
如今,在 IIS 中托管 ASP.NET Core 应用程序时的启动错误会生成更丰富的诊断数据。这些错误会在适用的状况下使用堆栈跟踪,报告给 Windows 事件日志。此外,全部的警告、错误和未处理的异常,都会记录到 Windows 事件日志中。
.NET Core 3.0 引入了新的辅助角色服务 (Worker Service) 应用模板。该模板是在 .NET Core 中编写长时间运行的服务的起点。
有关更多信息,请参见:
在早期版本的 ASP.NET Core 中,应用在部署到 Azure Linux 或者除 IIS 以外的任何反向代理以后,调用 UseHsts 和 UseHttpsRedirection 都是有问题的。转发 Linux 和非 IIS 反向代理的方案中介绍了之前版本的修复方式。
此场景已在 ASP.NET Core 3.0 中修复。当 ASPNETCORE_FORWARDEDHEADERS_ENABLED
环境变量设置为 true
时,主机将启用 Forwarded 标头中间件。在 ASP.NET Core 的容器镜像中,ASPNETCORE_FORWARDEDHEADERS_ENABLED
已被设置为 true
。
ASP.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。
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 3.0 共享程序集中移除的最值得注意的程序集是:
System.Text.Json
来读写 JSON。有关更多信息,请参阅本文档中新的 JSON 序列化。有关共享框架中所移除程序集的完整列表,请参阅 从 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