.NET 8 候选版本 2 (RC2) 现已可用

.NET 8 候选版本 2 (RC2) 现已可用,并包含了许多 ASP.NET Core 的出色新改进!

这是我们计划在今年晚些时候发布的最终 .NET 8 版本之前分享的最后一个候选版本。.NET 8 计划中的大部分功能和更改都已包含在此候选版本中,随时供您试用。您可以在文档中找到 .NET 8 中 ASP.NET Core 的新功能 的完整列表。

以下是此预览版本的新功能摘要:

  • 服务器和中间件
    • HTTP 日志扩展性
    • 更新到 IdentityModel 7x
  • API 创作
    • 在新的表单绑定中支持表单文件
  • SignalR
    • Typescript 客户端有状态重新连接支持
  • Blazor
    • Blazor Web 应用的全局互动性
    • Blazor WebAssembly 模板更新
    • 文件范围的 Razor 指令@rendermode
    • 增强的导航和表单处理改进
    • 当没有剩余的交互式服务器组件时关闭电路
    • 表单模型绑定改进
    • 作为一个级联参数访问HttpContext
    • 在 Blazor Web 应用中保持组件状态
    • 将键控服务注入到组件中
    • 对话框取消和关闭事件的支持
    • 错误页面支持
  • 身份验证
    • Blazor 身份验证 UI
  • 单页面应用 (SPA)
    • 从命令行运行新的 SPA 模板

有关 .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
  • 将所有 Microsoft.AspNetCore.* 包引用更新为 .8.0.0-rc.2.*
  • 将所有 Microsoft.Extensions.* 包引用更新为 .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 日志扩展性

HTTP 日志中间件具有几个新功能

  • HttpLoggingFields.Duration:启用后,此功能在请求/响应结束时发出一个新日志,测量处理所需的总时间(以毫秒为单位)。这已添加到集合中。HttpLoggingFields.All
  • HttpLoggingOptions.CombineLogs:启用后,中间件将在最后合并其为请求/响应启用的所有日志。这包括请求、请求体、响应、响应体和持续时间。
  • IHttpLoggingInterceptor:这是一个新的服务,可以实现和注册(),以便为自定义日志详情接收每个请求/响应的回调。任何特定于端点的日志设置首先都会被应用,然后可以在这些回调中被覆盖。实现可以检查请求/响应,启用或禁用任何/所有 , 调整记录请求/响应体的内容有多少,并向日志添加自定义参数。多个‘s 将按注册顺序运行。AddHttpLoggingInterceptor<T>``HttpLoggingFields``IHttpLoggingInterceptor

更新到 IdentityModel 7x

我们已经更新了 ASP.NET Core,以使用最新版本的 IdentityModel 库,IdentityModel 7x,其中包括利用更高性能的 JsonWebTokenHandler。这些库使得性能和 API 的一致性得到了改进,并且完全支持 Native AOT 兼容性。

API 创作

在新的表单绑定中支持表单文件

在 .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; }
}

SignalR

Typescript 客户端有状态重新连接支持

在早期的 .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

Blazor Web 应用的全球互动

Blazor Web 应用模板具有新的选项,可以为整个应用启用交互式渲染模式,而不仅仅是单个页面。全局启用交互式渲染模式意味着整个应用都变得交互式,包括路由器和布局。页面导航受益于客户端路由,每个页面都可以使用交互功能。这个选项在功能上与现有的 Blazor 服务器和 Blazor WebAssembly 应用程序非常相似。

创建 Blazor Web 应用时,您可以使用新的交互类型下拉列表选择要启用的交互渲染模式(再见复选框!):

Blazor Web 应用交互类型

然后,您可以指定交互位置,以便为整个应用或每个页面/组件启用:

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 或自动),那么所有组件及其依赖项都将被移动到客户端项目。

Blazor 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 项目模板进行了以下更新:

  • 将 Blazor WebAssembly 应用模板重命名为 Blazor WebAssembly 独立应用,以反映它在 .NET 8 中不再具有 ASP.NET Core 托管选项。要创建 ASP.NET Core 托管的 Blazor 应用,请使用 Blazor Web 应用模板,并启用 WebAssembly 交互渲染模式。
  • 删除了 Blazor WebAssembly 应用空项目模板,而是在 Blazor WebAssembly 模板中添加了一个选项,用于包含示例页面内容。
  • 清理了模板内容,使用与 Blazor Web 应用模板相同的名称和结构。

文件范围的 Razor 指令@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 Web应用程序将在预呈现期间自动持久化任何注册的状态,无需使用标记助手。

注入带键的服务到组件中

Blazor现在支持使用[Inject]属性注入带键的服务。键允许在使用依赖项注入时对注册和使用服务进行范围限定。使用新属性InjectAttribute.Key指定要注入的服务的键:

[Inject(Key = "my-service")]
public IMyService MyService { get; set; }

Razor指令目前还不支持带键的服务,但我们正在跟踪这个问题以在将来的版本中进行改进。

支持对话框取消和关闭事件

Blazor现在支持HTML元素上的cancelclose事件:

<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应用程序错误页面时,错误页面始终作为静态服务器组件呈现,即使在其他情况下启用了交互性。

Identity

Blazor身份界面

.NET 8 RC2支持在选择“个人帐户”身份验证选项时生成基于Blazor的完整身份界面。您可以在Visual Studio的Blazor Web应用程序的新项目对话框中选择“个人帐户”选项,或者在创建新项目时从命令行传递选项,如下所示:

dotnet new blazor -au Individual

在Visual Studio中,Blazor Web应用程序模板将为SQL Server数据库生成身份代码。命令行版本默认使用SQLite,并包含一个预先创建的SQLite数据库用于身份验证。

模板将为您处理以下事项:

  • 添加与身份验证相关的包和依赖项
  • _Imports.razor中引用身份包
  • 创建名为ApplicationUser的自定义身份类
  • 创建并注册一个EFCore DbContext
  • 添加并路由内置身份端点
  • 添加所有身份UI组件和相关逻辑
  • 包括身份验证和业务逻辑的验证

UI组件还支持高级身份验证概念,例如使用第三方应用程序的多因素身份验证和电子邮件确认。

团队还在努力为其他应用程序类型(包括Blazor WebAssembly和单页应用程序(Angular、React))构建身份验证示例。

我们鼓励您尝试这些新功能,并告诉我们您的想法以及我们可以做得更好的地方。请注意,在RC2

版本中,Blazor身份界面存在一些已知问题,这些问题列在本文末尾。

单页应用程序(SPA)

从命令行运行新的SPA模板

使用Visual Studio中的新ASP.NET Core SPA模板创建的应用程序现在可以在Windows和非Windows平台上使用.NET命令行界面运行。要运行应用程序,请使用dotnet run来运行服务器项目,然后自动启动前端JavaScript开发服务器。请注意,目前需要使用启动配置文件--launch-profile来运行应用程序。

已知问题

在此版本中存在一些已知问题,我们预计将在即将发布的.NET 8版本中解决。

  • 启用WebAssembly或全局自动交互呈现模式时,Blazor Web应用程序模板无法编译:当使用全局启用WebAssembly或自动交互呈现模式创建新的Blazor Web应用程序时,模板无法编译,因为错误页面错误地生成在客户端项目中。要解决此问题,请将Pages/Error.razor从客户端项目移动到服务器项目。
  • 在Blazor Web应用程序中提交表单时出现错误:“POST请求未指定要提交的表单”:在Blazor Web应用程序中提交有效表单时,可能会收到错误响应,指出“POST请求未指定要提交的表单”。这是由于本版本中指令属性的处理方式存在问题,将在即将发布的.NET 8版本中修复。要在开发期间强制执行注销操作,请使用浏览器开发工具清除身份验证Cookie。
  • Blazor身份界面问题:Blazor身份界面实现中的以下已知问题将在最终的.NET 8版本中得到解决:
    • 如果选择不具有交互性的身份验证,您将缺少在Program.cs中的命名空间的using指令,这会导致项目无法编译。您可以通过添加缺少的using指令来解决此问题,这是Visual Studio建议的自动修复。
    • Blazor身份界面在启用全局交互性的情况下(即--all-interactive)无法正常工作。如果在Blazor Web应用程序中同时启用身份验证和全局交互性,项目创建将成功,但交互性将仅在每个页面上启用。
    • 如果使用SQL Server,数据库错误页面上的“应用迁移”链接将无法正常工作。要解决此问题,您可以选择:调用dotnet ef database update来修复它,运行数据库错误页面建议的操作,或使用SQLite,我们为您生成了一个预先迁移的文件。
    • 在Blazor Web应用程序中,注销目前会失败,并显示错误:“POST请求未指定要提交的表单”,原因是前面提到的问题。此问题将在即将发布的.NET 8版本中修复。要在开发期间强制执行注销操作,请使用浏览器开发工具清除身份验证Cookie。

提供反馈

希望您喜欢.NET 8中ASP.NET Core的预览版本。请通过在GitHub上提交问题告诉我们您对这些新改进的看法。

感谢您尝试ASP.NET Core!

原文:https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-rc-2/

posted @ 2023-10-11 10:09  tokengo  阅读(790)  评论(2编辑  收藏  举报