.NET 8 候选版本 2 (RC2) 现已可用,并包含了许多 ASP.NET Core 的出色新改进!
这是我们计划在今年晚些时候发布的最终 .NET 8 版本之前分享的最后一个候选版本。.NET 8 计划中的大部分功能和更改都已包含在此候选版本中,随时供您试用。您可以在文档中找到 .NET 8 中 ASP.NET Core 的新功能 的完整列表。
以下是此预览版本的新功能摘要:
@rendermode
HttpContext
有关 .NET 8 中计划的 ASP.NET Core 工作的更多详细信息,请查看 GitHub 上的完整 .NET 8 的 ASP.NET Core 路线图。
要开始使用 .NET 8 RC2 中的 ASP.NET Core,请安装 .NET 8 SDK。
如果您在使用 Windows 上的 Visual Studio,我们建议安装最新的 Visual Studio 2022 预览版。如果您使用的是 Visual Studio Code,您可以尝试新的 C# Dev Kit。
要将现有的 ASP.NET Core 应用从 .NET 8 RC1 升级到 .NET 8 RC2:
net8.0
8.0.0-rc.2.*
8.0.0-rc.2.*
在 Blazor Web 应用中,您还需要更新任何引用交互式渲染模式的 API 调用以包含新的前缀:Interactive
.NET 8 RC1 | .NET 8 RC2 |
---|---|
Server |
InteractiveServer |
WebAssembly |
InteractiveWebAssembly |
Auto |
InteractiveAuto |
此外,我们将属性重命名为 .Handler``SupplyParameterFromFormAttribute``FormName
还可以查看 .NET 8 中 ASP.NET Core 的完整破坏性更改列表。
HTTP 日志中间件具有几个新功能:
HttpLoggingFields.Duration
:启用后,此功能在请求/响应结束时发出一个新日志,测量处理所需的总时间(以毫秒为单位)。这已添加到集合中。HttpLoggingFields.All
HttpLoggingOptions.CombineLogs
:启用后,中间件将在最后合并其为请求/响应启用的所有日志。这包括请求、请求体、响应、响应体和持续时间。IHttpLoggingInterceptor
:这是一个新的服务,可以实现和注册(),以便为自定义日志详情接收每个请求/响应的回调。任何特定于端点的日志设置首先都会被应用,然后可以在这些回调中被覆盖。实现可以检查请求/响应,启用或禁用任何/所有 , 调整记录请求/响应体的内容有多少,并向日志添加自定义参数。多个‘s 将按注册顺序运行。AddHttpLoggingInterceptor<T>``HttpLoggingFields``IHttpLoggingInterceptor
我们已经更新了 ASP.NET Core,以使用最新版本的 IdentityModel 库,IdentityModel 7x,其中包括利用更高性能的 JsonWebTokenHandler。这些库使得性能和 API 的一致性得到了改进,并且完全支持 Native AOT 兼容性。
在 .NET 8 预览 6 中,我们引入了对最小 API 的复杂表单绑定支持,使用由 Blazor 共享的映射基础结构。在 RC2 中,这个表单绑定实现现在支持绑定包含 property 的类型。IFormFile
以下示例通过属性提供对上传文件的访问。DocumentUpload.Document
var app = WebApplication.Create();
app.MapPost("/upload", ([FromForm] DocumentUpload document
) =>
{
return Results.Ok();
});
app.Run();
public class DocumentUpload
{
public string Name { get; set; } = "Uploaded Document";
public string? Description { get; set; }
public IFormFile? Document { get; set; }
}
在早期的 .NET 8 预览中,我们为 .NET 客户端添加了有状态重新连接的支持。该功能现在在 TypeScript 客户端中也可用。
此功能旨在减少由于切换网络连接、驾驶穿过隧道等原因造成的网络连接暂时中断的客户端的感知停机时间。它通过在服务器和客户端上临时缓冲数据并确认双方发送的消息,以及识别何时连接返回并重放在连接中断时可能已发送的消息来实现这一点。
要选择加入该功能,请更新您的 TypeScript/JavaScript 客户端代码以启用该选项:
const builder = new signalR.HubConnectionBuilder()
.withUrl("/hubname")
.withStatefulReconnect({ bufferSize: 1000 }); // 可选的选项,默认为 100,000
const connection = builder.build();
服务器还需要在客户端访问的端点上启用支持:
app.MapHub<MyHub>("/hubName", options =>
{
options.AllowStatefulReconnects = true;
});
Blazor Web 应用模板具有新的选项,可以为整个应用启用交互式渲染模式,而不仅仅是单个页面。全局启用交互式渲染模式意味着整个应用都变得交互式,包括路由器和布局。页面导航受益于客户端路由,每个页面都可以使用交互功能。这个选项在功能上与现有的 Blazor 服务器和 Blazor WebAssembly 应用程序非常相似。
创建 Blazor Web 应用时,您可以使用新的交互类型下拉列表选择要启用的交互渲染模式(再见复选框!):
然后,您可以指定交互位置,以便为整个应用或每个页面/组件启用:
如果您全局启用交互性,那么根组件中的任何组件都将使用所选的渲染模式。例如,如果您全局启用了自动渲染模式,那么您的 App.razor 将如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorApp14.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet @rendermode="@RenderMode.InteractiveAuto" />
</head>
<body>
<Routes @rendermode="@RenderMode.InteractiveAuto" />
</body>
</html>
如果您的应用使用基于 WebAssembly 的交互式渲染模式(WebAssembly 或自动),那么所有组件及其依赖项都将被移动到客户端项目。
在 .NET 8 中,我们一直在努力整合 Blazor 项目模板,围绕新的全栈 Web UI 支持。现在大多数 Blazor 场景都由 Blazor Web 应用模板处理,该模板将服务器和基于客户端的 Web UI 开发的优势结合成一个统一的模型。但仍然存在可能需要在没有 ASP.NET Core 服务器的情况下作为静态站点托管 Blazor 应用的情况。例如,您可能希望在 GitHub Pages 或 Azure 静态 Web 应用上托管 Blazor 应用。对于静态站点,Blazor WebAssembly 仍然是正确的解决方案。
在 .NET 8 RC2 中,我们对 Blazor WebAssembly 项目模板进行了以下更新:
@rendermode
Razor 指令现在可以在文件范围内应用,以在组件定义上指定渲染模式,而不是使用现有的渲染模式属性。@rendermode
指令接受一个类型为 的参数,就像它在组件实例上用作 Razor 指令属性时一样。静态类为当前支持的渲染模式提供了便
利属性:, 和 。您可以在您的 _Imports.razor 文件中使用指令简化对这些渲染模式属性的访问。@rendermode``IComponentRenderMode``RenderMode``InteractiveServer``InteractiveWebAssembly``InteractiveAuto``using static
_Imports.razor
@using static Microsoft.AspNetCore.Components.Web.RenderMode
Counter.razor
@rendermode InteractiveServer
您还可以引用直接使用自定义配置实例化的静态渲染模式实例,例如禁用预渲染。
@rendermode renderMode
@code {
static IComponentRenderMode renderMode = new InteractiveWebAssemblyRenderMode(prerender: false);
}
以下是现有渲染模式属性如何映射到新的 Razor 语法:
[RenderModeXxx] 属性 |
@rendermode 指令 |
---|---|
@attribute [RenderModeInteractiveServer] |
@rendermode InteractiveServer |
@attribute [RenderModeInteractiveWebAssembly] |
@rendermode InteractiveWebAssembly |
@attribute [RenderModeInteractiveAuto] |
@rendermode InteractiveAuto |
Blazor Web 应用模板尚未更新为使用新语法代替现有的渲染模式属性,但我们计划在最终的 .NET 8 版本中进行此更改。@rendermode
.NET 8 中的 Blazor 通过拦截请求并智能地使用服务器的静态渲染内容更新 DOM 来增强导航和表单处理。在此版本中,我们对增强的导航和表单处理的工作方式进行了一些改进,这样您就可以更好地控制何时应用增强,并使增强与其他非 Blazor 页面很好地集成。
控制何时使用增强导航
当您添加 Blazor 脚本 (blazor.web.js) 时,默认启用增强导航。增强导航仅支持基于 Blazor 的页面。在应用内部导航到非 Blazor 端点时,Blazor 将重试请求,但不使用增强导航。为了避免这种重复的请求,您可以控制点击链接是否导致增强导航,方法是将属性应用于锚标签或任何祖先元素。data-enhance-nav
<a href="my-non-blazor-page" data-enhance-nav="false">我的非 Blazor 页面</a>
启用增强的表单处理
在此版本中,默认不启用增强的表单处理,以避免表单重定向到非 Blazor 页面的问题。要启用增强的表单处理,请在元素上使用属性,或使用参数在上使用。data-enhance``form``Enhance``EditForm
<form method="post" @onsubmit="() => submitted = true" @formname="name" data-enhance>
<AntiforgeryToken />
<InputText @bind-Value="Name" />
<button>提交</button>
</form>
@if (submitted)
{
<p>你好 @Name!</p>
}
@code{
bool submitted;
[SupplyParameterFromForm]
public string Name { get; set; } = "";
}
<EditForm method="post" Model="NewCustomer" OnValidSubmit="() => submitted = true" FormName="customer" Enhance>
<DataAnnotationsValidator />
<ValidationSummary/>
<p>
<label>
名称: <InputText @bind-Value="NewCustomer.Name" />
</label>
</p>
<button>提交</button>
</EditForm>
@if (submitted)
{
<p id="pass">你好 @NewCustomer.Name!</p>
}
@code {
bool submitted = false;
[SupplyParameterFromForm]
public Customer? NewCustomer { get; set; }
protected override void OnInitialized()
{
NewCustomer ??= new();
}
public class Customer
{
[StringLength(3, ErrorMessage = "名字太长")]
public string? Name { get; set; }
}
}
重定向到非 Blazor 端点的增强表单将导致错误。
使用增强的导航和表单处理保留内容
Blazor 的增强导航和表单处理可能会撤消对 DOM 的任何动态更改,如果更新的内容不是服务器渲染的一部分。要指示元素的内容应被保留,请使用新的属性。data-permanent
<div data-permanent>
当页面加载时,此 div 由脚本动态更新!
</div>
增强加载事件
一旦 Blazor 在客户端上启动,您就可以使用事件来监听增强页面更新,包括流式更新。这允许重新应用可能被增强页面更新撤销的对 DOM 的更改。enhancedload
Blazor.addEventListener('enhancedload', () => console.log('进行了增强更新!'));
交互式服务器组件使用与浏览器的实时连接,称为电路,处理Web UI事件。当呈现根交互式服务器组件时,将设置电路及其关联状态。在.NET 8 RC2中,当页面上没有剩余的交互式服务器组件时,电路将被关闭,从而释放服务器资源。
Blazor中的表单模型绑定现在将遵循数据合同属性([DataMember]
、[IgnoreDataMember]
等)以自定义如何将表单数据绑定到模型。
<EditForm method="post" Model="NewCustomer" OnValidSubmit="() => submitted = true" FormName="customer" Enhance>
<DataAnnotationsValidator />
<ValidationSummary/>
<p>
<label>
Name: <InputText @bind-Value="NewCustomer.Name" />
</label>
</p>
<input type="hidden" name="Parameter.Id" value="1" />
<button>Submit</button>
</EditForm>
@if (submitted)
{
<p id="pass">Hello @NewCustomer.Name!</p>
}
@code {
bool submitted = false;
[SupplyParameterFromForm]
public Customer? NewCustomer { get; set; }
protected override void OnInitialized()
{
NewCustomer ??= new();
}
public class Customer
{
[IgnoreDataMember]
public int Id { get; set; }
[StringLength(3, ErrorMessage = "Name is too long")]
[DataMember(Name = "FirstName")]
public string Name { get; set; }
}
}
HttpContext
现在,您可以从静态服务器组件中作为级联参数访问当前HttpContext
。
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
从静态服务器组件中访问HttpContext
可能对检查和修改标头或其他属性很有用。
现在,您可以在Blazor Web应用程序中使用现有服务持久化和读取组件状态。这对于在预呈现期间持久化组件状态非常有用。Blazor Web应用程序将在预呈现期间自动持久化任何注册的状态,无需使用标记助手。
Blazor现在支持使用[Inject]
属性注入带键的服务。键允许在使用依赖项注入时对注册和使用服务进行范围限定。使用新属性InjectAttribute.Key
指定要注入的服务的键:
[Inject(Key = "my-service")]
public IMyService MyService { get; set; }
Razor指令目前还不支持带键的服务,但我们正在跟踪这个问题以在将来的版本中进行改进。
Blazor现在支持HTML元素上的cancel
和close
事件:
<div>
<p>Output: @message</p>
<button onclick="document.getElementById('my-dialog').showModal()">
Show modal dialog
</button>
<dialog id="my-dialog" @onclose="OnClose" @oncancel="OnCancel">
<p>Hi there!</p>
<form method="dialog">
<button>Close</button>
</form>
</dialog>
</div>
@code {
string message;
void OnClose(EventArgs e) => message += "onclose,";
void OnCancel(EventArgs e) => message += "oncancel,";
}
感谢@campersau为此贡献!
Blazor Web应用程序现在可以为ASP.NET Core异常处理中间件定义自定义错误页面。我们已更新Blazor Web应用程序项目模板,包括一个默认的错误页面(Components/Pages/Error.razor),其内容与MVC和Razor页面应用程序中使用的内容类似。当以响应来自异常处理中间件的请求渲染Blazor Web应用程序错误页面时,错误页面始终作为静态服务器组件呈现,即使在其他情况下启用了交互性。
.NET 8 RC2支持在选择“个人帐户”身份验证选项时生成基于Blazor的完整身份界面。您可以在Visual Studio的Blazor Web应用程序的新项目对话框中选择“个人帐户”选项,或者在创建新项目时从命令行传递选项,如下所示:
dotnet new blazor -au Individual
在Visual Studio中,Blazor Web应用程序模板将为SQL Server数据库生成身份代码。命令行版本默认使用SQLite,并包含一个预先创建的SQLite数据库用于身份验证。
模板将为您处理以下事项:
_Imports.razor
中引用身份包ApplicationUser
的自定义身份类UI组件还支持高级身份验证概念,例如使用第三方应用程序的多因素身份验证和电子邮件确认。
团队还在努力为其他应用程序类型(包括Blazor WebAssembly和单页应用程序(Angular、React))构建身份验证示例。
我们鼓励您尝试这些新功能,并告诉我们您的想法以及我们可以做得更好的地方。请注意,在RC2
版本中,Blazor身份界面存在一些已知问题,这些问题列在本文末尾。
使用Visual Studio中的新ASP.NET Core SPA模板创建的应用程序现在可以在Windows和非Windows平台上使用.NET命令行界面运行。要运行应用程序,请使用dotnet run
来运行服务器项目,然后自动启动前端JavaScript开发服务器。请注意,目前需要使用启动配置文件--launch-profile
来运行应用程序。
在此版本中存在一些已知问题,我们预计将在即将发布的.NET 8版本中解决。
using
指令,这会导致项目无法编译。您可以通过添加缺少的using
指令来解决此问题,这是Visual Studio建议的自动修复。--all-interactive
)无法正常工作。如果在Blazor Web应用程序中同时启用身份验证和全局交互性,项目创建将成功,但交互性将仅在每个页面上启用。dotnet ef database update
来修复它,运行数据库错误页面建议的操作,或使用SQLite,我们为您生成了一个预先迁移的文件。希望您喜欢.NET 8中ASP.NET Core的预览版本。请通过在GitHub上提交问题告诉我们您对这些新改进的看法。
感谢您尝试ASP.NET Core!
原文:https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-rc-2/