当前位置:闪电软件园 > 系统 > 运行时库 >

Microsoft .NET Runtime(.NET8.0) 8.0.4 Build 33519

(认准闪电软件园)
  • 浏览(
  • 更新时间:2024-04-10
  • 软件大小:未知
  • 界面语言:简体中文
  • 授权方式:共享软件
  • 运行环境:Win7/win8/win10
  • 官方网站:闪电软件园

软件标签:.NET8.0 
Microsoft .NET Runtime(.NET8.0)为构建.NET Framework应用程序提供必要的基础类型库组件,能够有效确保应用程序运行和开发的顺畅进行下去,必备的运行时库,保障程序的安装和使用,是windows操作系统构建各种应用所必不可少的基础类型库组件。免费的跨平台开放源代码开发人员平台,用于生成多种类型的应用程序。基于许多大规模应用在生产中使用的高性能运行时构建而来。最新8.0版本,

 8.0 的新增功能

1、Blazor
·全堆栈 Web UI
随着 .NET 8 的发布,Blazor 已成为全堆栈 Web UI 框架,可用于开发在组件或页面级别呈现内容的应用,其中包含:
用于生成静态 HTML 的静态服务器呈现。
使用 Blazor Server 托管模型的交互式服务器呈现。
使用 Blazor WebAssembly 托管模型的交互式客户端呈现。
下载 Blazor 捆绑包并激活 .NET WebAssembly 运行时后,最初使用 Blazor Server,并在随后访问时使用 WebAssembly 自动进行交互式客户端呈现。 自动呈现通常会提供最快的应用启动体验。
默认情况下,交互式呈现模式还会预呈现内容。
·新的 Blazor Web 应用模板
我们引入了一个新的 Blazor 项目模板:Blazor Web 应用 模板。 新模板提供了使用 Blazor 组件生成任何样式的 Web UI 的单个起点。 该模板将现有 Blazor Server 和 Blazor WebAssembly 托管模型的优势与 .NET 8 中添加的新功能 Blazor 相结合:静态服务器呈现、流呈现、增强的导航和表单处理,以及使用 Blazor Server 或 Blazor WebAssembly 按组件添加交互性的功能。
作为将各种 Blazor 托管模型统一到 .NET 8 中单个模型的一部分,我们还合并了 Blazor 项目模板的数量。 我们移除了 Blazor Server 模板,并从 Blazor WebAssembly 模板中移除了 ASP.NET Core 托管选项。 这两种方案都由使用 Blazor Web 应用模板时的选项表示。
 备注
.NET 8 仍然支持现有的 Blazor Server 和 Blazor WebAssembly 应用。 可以选择更新这些应用,以使用新的全堆栈 Web UI Blazor 功能。
·在 Blazor Web 应用中保留组件状态
可以使用现有 PersistentComponentState 服务在 Blazor Web 应用中保留和读取组件状态。 这对预呈现期间保留组件状态非常有用。 Blazor Web 应用会在预呈现期间自动保留任何已注册状态,无需 保留组件状态标记帮助程序。
·表单处理和模型绑定
现在,Blazor 组件可以处理提交的表单请求,包括模型绑定和验证请求数据。 组件可以使用标准 HTML <form> 标记或使用现有的 EditForm 组件通过单独的表单处理程序实现窗体。
表单模型绑定 Blazor 遵循数据协定属性(例如 [DataMember] 和 [IgnoreDataMember]),用于自定义表单数据绑定到模型的方式。
.NET 8 中包括新的防伪支持。 新的 AntiforgeryToken 组件可将防伪标记呈现为隐藏字段,而新的 [RequireAntiforgeryToken] 属性可启用防伪保护。 如果防伪检查失败,将会返回 400(错误的请求)响应,而无需进行表单处理。 默认情况下,基于 Editform 的表单会启用新的防伪功能,并且可以将其手动应用于标准 HTML 表单。
·增强的导航和表单处理
每当用户导航到新页面或提交表单时,静态服务器呈现通常会执行整页刷新。 在 .NET 8 中,Blazor 可以通过截获请求并改为执行提取请求来增强页面导航和表单处理。 然后,Blazor 会通过将呈现的响应内容修补到浏览器 DOM 中来处理它。 增强的导航和表单处理可避免需要全页刷新并保留更多页面状态,因此页面加载速度更快、更流畅。 默认情况下,当加载 Blazor 脚本(blazor.web.js)时,会启用增强导航。 可以选择为特定表单启用增强的表单处理。
新的增强型导航 API 可以让你通过调用 NavigationManager.Refresh(bool forceLoad = false) 来刷新当前页。
·流式渲染
现在,在将静态服务器呈现与 Blazor 结合使用时,可以在响应流中流式传输内容更新。 流式呈现可以改善执行长期运行异步任务的页面的用户体验,以便在内容可用后立即通过呈现内容来完全呈现。
例如,要呈现页面,可能需要进行长期运行的数据库查询或 API 调用。 通常,作为呈现页面其中一部分来执行的异步任务必须在发送已呈现的响应之前完成,这会导致页面加载延迟。 流式呈现最初会呈现包含占位符内容的整个页面,同时执行异步操作。 异步操作完成后,更新后的内容将在同一响应连接上发送到客户端,并修补到 DOM 中。 此方法的优点是,应用的主要布局将会尽快呈现,并在内容就绪后立即更新页面。
·将键控服务注入组件
Blazor 现在支持使用 [Inject] 属性注入键控服务。 密钥允许在使用依赖项注入时界定服务的注册和使用范围。 使用新 InjectAttribute.Key 属性指定服务要注入的密钥:

@injectRazor 指令尚不支持键控服务,但会跟踪工作,以便针对将来的版本对此进行改进。
·以级联参数形式访问 HttpContext
现在可以从静态服务器组件以级联参数形式访问当前 HttpContext:

·在 ASP.NET Core 之外呈现 Razor 组件
现在,可以在 HTTP 请求的上下文之外呈现 Razor 组件。 可以独立于 ASP.NET Core 托管环境,将 Razor 组件作为 HTML 直接呈现为字符串或数据流。 对于要生成 HTML 片段(例如生成电子邮件或静态网站内容)的方案,这会非常方便。
·节支持
Blazor 中的新 SectionOutlet 和 SectionContent 组件添加了对于为可在稍后填充的内容指定出口的支持。 节通常用于在布局中定义随后由特定页面填充的占位符。 节由唯一名称或使用唯一对象 ID 引用。
·错误页支持
Blazor Web 应用可定义用于 ASP.NET 核心异常处理中间件的自定义错误页。 Blazor Web 应用项目模板包括默认错误页(Components/Pages/Error.razor),其内容与 MVC 和 Razor Pages 应用中使用的内容相似。 在响应异常处理中间件的请求时呈现错误页时,即使启用交互性,错误页也始终呈现为静态服务器组件。
·QuickGrid
Blazor QuickGrid 组件不再处于试验阶段,并且现在已是 .NET 8 中框架 Blazor 的一部分。
 
QuickGrid 是一个高性能网格组件,可用于以表格形式显示数据。 QuickGrid 旨在提供一种简单便捷的方式来显示数据,同时仍提供强大的功能,例如排序、筛选、分页和虚拟化。
·路由到命名元素
现在,Blazor 支持使用客户端路由,以通过标准 URL 片段导航到页面上的特定 HTML 元素。 如果使用标准 id 属性指定 HTML 元素的标识符,则当 URL 片段与元素标识符匹配时,Blazor 会正确滚动到该元素。
·根级别级联值
可以为整个组件层次结构注册根级别级联值。 支持用于更新通知的命名级联值和订阅。
·虚拟化空内容
当 Virtualize 组件已加载,并且 Items 为空或 ItemsProviderResult<T>.TotalItemCount 为零时,使用该组件上的 EmptyContent 参数提供内容。
·当没有剩余的交互式服务器组件时,关闭线路
交互式服务器组件使用与浏览器的实时连接(称为线路)来处理 Web UI 事件。 呈现根交互式服务器组件时,将设置线路及其关联状态。 当页面上没有剩余的交互式服务器组件时,线路将关闭,以释放服务器资源。
·监视 SignalR 线路活动
现在,可以使用 CircuitHandler 上的 CreateInboundActivityHandler 方法监视服务器端应用中的入站线路活动。 入站线路活动是从浏览器发送到服务器的任何活动,例如 UI 事件或 JavaScript 到 .NET 的互操作调用。
·使用 Jiterpreter 提高运行时性能
Jiterpreter 是 .NET 8 中的一项新运行时功能,可以在 WebAssembly 上运行时启用部分实时 (JIT) 编译支持,以提高运行时性能。
有关详细信息,请参阅托管和部署 ASP.NET Core Blazor WebAssembly。
·预先 (AOT) SIMD 和异常处理
现在,Blazor WebAssembly 预先 (AOT) 编译默认使用 WebAssembly 固定宽度 SIMD 和 WebAssembly 异常处理来提高运行时性能。
Web 友好 Webcil 打包
Webcil 是 .NET 程序集的 Web 友好打包,可移除特定于本机 Windows 执行的内容,以避免部署到阻止下载或使用 .dll 文件的环境时出现问题。 默认情况下,Blazor WebAssembly 应用会启用 Webcil。
 
有关详细信息,请参阅托管和部署 ASP.NET Core Blazor WebAssembly。
 
Blazor WebAssembly 调试改进
在 WebAssembly 上调试 .NET 时,调试器现在将从 Visual Studio 首选项中配置的符号位置下载符号数据。 这改进了使用 NuGet 包的应用的调试体验。
 
现在,可以使用 Firefox 调试 Blazor WebAssembly 应用。 调试 Blazor WebAssembly 应用需要配置浏览器以进行远程调试,然后通过 .NET WebAssembly 调试代理使用浏览器开发人员工具连接到浏览器。 目前不支持从 Visual Studio 调试 Firefox。
 
有关详细信息,请参阅调试 ASP.NET Core Blazor 应用。
 
内容安全策略 (CSP) 兼容性
zai 指定内容安全策略 (CSP) 时,Blazor WebAssembly 不再需要启用 unsafe-eval 脚本源。
 
有关详细信息,请参阅为 ASP.NET Core Blazor 强制实施内容安全策略。
 
在 Razor 组件的生命周期外处理捕获的异常
在 Razor 组件中使用 ComponentBase.DispatchExceptionAsync 来处理在组件的生命周期调用堆栈外部引发的异常。 这允许组件的代码将异常视为生命周期方法异常。 此后,Blazor 的错误处理机制(如错误边界)可以处理异常。
 
有关详细信息,请参阅处理 ASP.NET Core Blazor 应用中的错误。
 
配置 .NET WebAssembly 运行时
现在可以为 .NET WebAssembly 运行时配置 Blazor 启动。
 
有关详细信息,请参阅 ASP.NET Core Blazor 启动。
 
配置 HubConnectionBuilder 中的连接超时
配置中心连接超时的先前解决方法可以替换为正式的 SignalR 中心连接生成器超时配置。
 
有关详细信息,请参阅以下部分:
 
ASP.NET Core BlazorSignalR 指南
托管和部署 ASP.NET Core Blazor WebAssembly
托管和部署 ASP.NET Core 服务器端 Blazor 应用
项目模板库 Open Iconic
Blazor 项目模板不再依赖于图标的 Open Iconic。
 
支持对话框取消和关闭事件
Blazor 现在支持 dialog HTML 元素上的 cancel 和 close 事件。
 
如下示例中:
 
使用“关闭”按钮关闭 my-dialog 对话框时,会调用 OnClose。
使用 Esc 键取消对话框时会调用 OnCancel。 使用 Esc 键消除 HTML 对话框时,将触发 cancel 和 close 事件。
razor
 
复制
<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 {
    private string? message;
 
    private void OnClose(EventArgs e) => message += "onclose, ";
 
    private void OnCancel(EventArgs e) => message += "oncancel, ";
}
BlazorIdentity UI
选择个人帐户的身份验证选项时,Blazor 支持生成基于 Blazor 的完整 Identity UI。 可以在 Visual Studio 的 Blazor Web 应用的新项目对话框中为“个人帐户”选择该选项,或者在创建新项目时从命令行传递该选项:
 
.NET CLI
 
复制
dotnet new blazor -au Individual
在 Visual Studio 中,Blazor Web 应用模板为 SQL Server 数据库搭建 Identity 代码基架。 命令行版本默认使用 SQLite,并包含 Identity 的 SQLite 数据库。
 
该模板处理以下内容:
 
添加 Identity 相关的包和依赖项
引用 _Imports.razor 中的 Identity 包
创建名为“ApplicationUser”的自定义 Identity 类
创建并注册 EFCore DbContext
添加并路由内置 Identity 终结点
添加所有 Identity UI 组件和相关逻辑
包含 Identity 验证和业务逻辑
UI 组件还支持高级 Identity 概念,例如使用第三方应用和电子邮件确认的多重身份验证。
 
其他应用类型的身份验证示例正在开发中,包括 Blazor WebAssembly 和单页应用(Angular、React)。
 
SignalR
设置服务器超时和保持活动间隔的新方法
ServerTimeout(默认值:30 秒)和 KeepAliveInterval(默认值:15 秒)可以直接在 HubConnectionBuilder 上设置。
 
适用于 JavaScript 客户端的先前方法
下面的示例演示了 ASP.NET Core 7.0 或更早版本中默认值的两倍值的分配:
 
JavaScript
 
复制
var connection = new signalR.HubConnectionBuilder()
  .withUrl("/chatHub")
  .build();
 
connection.serverTimeoutInMilliseconds = 60000;
connection.keepAliveIntervalInMilliseconds = 30000;
适用于 JavaScript 客户端的新方法
下面的示例演示了分配 ASP.NET Core 8.0 或更高版本中默认值的两倍值的新方法:
 
JavaScript
 
复制
var connection = new signalR.HubConnectionBuilder()
  .withUrl("/chatHub")
  .withServerTimeoutInMilliseconds(60000)
  .withKeepAliveIntervalInMilliseconds(30000)
  .build();
Blazor Server 应用的 JavaScript 客户端的先前方法
下面的示例演示了 ASP.NET Core 7.0 或更早版本中默认值的两倍值的分配:
 
JavaScript
 
复制
Blazor.start({
  configureSignalR: function (builder) {
    let c = builder.build();
    c.serverTimeoutInMilliseconds = 60000;
    c.keepAliveIntervalInMilliseconds = 30000;
    builder.build = () => {
      return c;
    };
  }
});
服务器端 Blazor 应用的 JavaScript 客户端的新方法
以下示例显示了为 Blazor Web 应用和 Blazor Server 分配两倍于 ASP.NET Core 8.0 或更高版本中默认值的值的新方法。
 
Blazor Web 应用:
 
JavaScript
 
复制
Blazor.start({
  circuit: {
    configureSignalR: function (builder) {
      builder.withServerTimeout(60000).withKeepAliveInterval(30000);
    }
  }
});
Blazor Server:
 
JavaScript
 
复制
Blazor.start({
  configureSignalR: function (builder) {
    builder.withServerTimeout(60000).withKeepAliveInterval(30000);
  }
});
.NET 客户端的先前方法
下面的示例演示了 ASP.NET Core 7.0 或更早版本中默认值的两倍值的分配:
 
C#
 
复制
var builder = new HubConnectionBuilder()
    .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
    .Build();
 
builder.ServerTimeout = TimeSpan.FromSeconds(60);
builder.KeepAliveInterval = TimeSpan.FromSeconds(30);
 
builder.On<string, string>("ReceiveMessage", (user, message) => ...
 
await builder.StartAsync();
.NET 客户端的新方法
下面的示例演示了分配 ASP.NET Core 8.0 或更高版本中默认值的两倍值的新方法:
 
C#
 
复制
var builder = new HubConnectionBuilder()
    .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
    .WithServerTimeout(TimeSpan.FromSeconds(60))
    .WithKeepAliveInterval(TimeSpan.FromSeconds(30))
    .Build();
 
builder.On<string, string>("ReceiveMessage", (user, message) => ...
 
await builder.StartAsync();
SignalR 有状态重新连接
SignalR 有状态重新连接可减少客户端遇到暂时断开网络连接(例如,切换网络连接时或短暂的暂时失去访问权限时)情况时感知到的停机时间。
 
有状态重新连接可通过以下方式实现此目的:
 
暂时缓冲服务器和客户端上的数据。
确认服务器和客户端(确认)收到的消息。
识别连接何时返回并重播在连接关闭时可能已发送的消息。
选择加入 JavaScript 或 TypeScript 客户端的有状态重新连接:
 
更新 JavaScript 或 TypeScript 客户端代码,以启用 withStatefulReconnect 选项:
 
JavaScript
 
复制
const builder = new signalR.HubConnectionBuilder()
  .withUrl("/hubname")
  .withStatefulReconnect({ bufferSize: 1000 });  // Optional, defaults to 100,000
const connection = builder.build();
更新服务器中心终结点配置以启用 AllowStatefulReconnects 选项:
 
C#
 
复制
app.MapHub<MyHub>("/hubName", options =>
{
    options.AllowStatefulReconnects = true;
});
选择加入 .NET 客户端的有状态重新连接:
 
更新 .NET 客户端代码以启用 WithStatefulReconnect 选项:
 
C#
 
复制
  var builder = new HubConnectionBuilder()
      .WithUrl("<hub url>")
      .WithStatefulReconnect();
  builder.Services.Configure<HubConnectionOptions>(o => o.StatefulReconnectBufferSize = 1000);
  var hubConnection = builder.Build();
更新服务器中心终结点配置以启用 AllowStatefulReconnects 选项:
 
C#
 
复制
app.MapHub<MyHub>("/hubName", options =>
{
    options.AllowStatefulReconnects = true;
});
最小 API
本部分介绍最小 API 的新功能。 另请参阅本机 AOT 部分,详细了解最小 API。
 
用户替代区域性
从 ASP.NET Core 8.0 开始,应用程序可通过 RequestLocalizationOptions.CultureInfoUseUserOverride 属性来确定是否对 CultureInfoDateTimeFormat 和 NumberFormat 属性使用非默认的 Windows 设置。 这对 Linux 没有影响。 这直接对应于 UseUserOverride。
 
C#
 
复制
    app.UseRequestLocalization(options =>
    {
        options.CultureInfoUseUserOverride = false;
    });
绑定到表单
现在支持使用 [FromForm] 属性显式绑定到表单值。 通过 [FromForm] 绑定到请求的参数包括防伪令牌。 处理请求时会验证防伪令牌。
 
还支持使用 IFormCollection、IFormFile 和 IFormFileCollection 类型推断绑定到表单。 OpenAPI 元数据针对表单参数进行推断,以支持与 Swagger UI 集成。
 
有关详细信息,请参阅:
 
从窗体值显式绑定。
使用 IFormCollection、IFormFile 和 IFormFileCollection 绑定到表单。
最小 API 中的窗体绑定
现在针对以下内容支持从表单绑定:
 
集合,例如列表和字典
复杂类型,例如 Todo 或 Project
有关详细信息,请参阅从表单绑定到集合和复杂类型。
 
使用最少 API 进行防伪造
此版本添加了用于验证反伪令牌的中间件,用于缓解跨站点请求伪造攻击。 调用 AddAntiforgery 以在 DI 中注册防伪服务。 在 DI 容器中注册防伪服务时,WebApplicationBuilder 会自动添加防伪中间件。 防伪令牌用于减少跨站点请求伪造攻击。
 
C#
 
复制
var builder = WebApplication.CreateBuilder();
 
builder.Services.AddAntiforgery();
 
var app = builder.Build();
 
// Implicitly added by WebApplicationBuilder
// app.UseAntiforgery();
 
app.MapGet("/", () => "Hello World!");
 
app.Run();
防伪中间件:
 
不请求管道其余部分的执行短路。
在当前请求的 HttpContext.Features 中设置 IAntiforgeryValidationFeature。
仅当出现以下情况时,才会验证防伪令牌:
 
终结点包含实现 IAntiforgeryMetadata 的元数据,其中 RequiresValidation=true。
与终结点关联的 HTTP 方法是一个相关的 HTTP 方法。 除了 TRACE、OPTIONS、HEAD 和 GET 之外,相关方法都是 HTTP 方法。
请求与某个有效的终结点关联。
有关详细信息,请参阅用最小 API 实现防伪。
 
支持 AsParameters 和自动元数据生成
编译时生成的最小 API 支持使用 [AsParameters] 属性修饰的参数,并支持请求和响应类型的自动元数据推理。 考虑下列代码:
 
C#
 
复制
using System.Text.Json.Serialization;
using MyFirstAotWebApi;
 
var builder = WebApplication.CreateSlimBuilder(args);
 
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
 
var app = builder.Build();
 
var sampleTodos = TodoGenerator.GenerateTodos().ToArray();
 
var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());
 
app.MapPost("/todos", ([AsParameters] CreateTodoArgs payload) =>
{
    if (payload.TodoToCreate is not null)
    {
        return payload.TodoToCreate;
    }
    return new Todo(0, "New todo", DateTime.Now, false);
});
 
app.Run();
 
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
 
}
 
record CreateTodoArgs(int ProjectId, Todo? TodoToCreate);
record Todo(int Id, string Name, DateTime CreatedAt, bool IsCompleted);
前面生成的代码:
 
从查询绑定 projectId 参数。
从 JSON 正文绑定 Todo 参数。
对终结点元数据进行注释,以表明其接受 JSON 有效负载。
对终结点元数据进行注释以表明其会以 JSON 有效负载的形式返回一个待办事项。
在 ObjectPool 中新建 IResettable 接口
Microsoft.Extensions.ObjectPool 为内存中的池对象实例提供支持。 如果值分配或初始化成本较高,则应用可以使用对象池。
 
在此版本中,我们通过添加 IResettable 接口,使对象池更易于使用。 可重用类型通常需要在使用之间重置回默认状态。 返回到对象池时,IResettable 类型将自动重置。
 
有关详细信息,请参阅 ObjectPool 示例。
 
本机 AOT
添加了对 .NET 本机预先 (AOT) 的支持。 使用 AOT 发布的应用的性能要好得多:更小的应用大小、更少的内存使用量和更快的启动时间。 gRPC、最小 API 和工作器服务应用目前支持本机 AOT。 有关详细信息,请参阅 ASP.NET Core 对本机 AOT 的支持和教程:使用本机 AOT 发布 ASP.NET Core 应用。 如需了解 ASP.NET Core 与本机 AOT 的兼容性的已知问题,请参阅 GitHub 问题 dotnet/core #8288。
 
库和本机 AOT
目前,在 ASP.NET Core 项目中使用的许多常用库在针对本机 AOT 的项目中使用时都存在一些兼容性问题,例如:
 
使用反射来检查和发现类型。
在运行时有条件地加载库。
动态生成代码以实现功能。
使用这些动态功能的库需要更新才能与本机 AOT 配合使用。 可以使用 Roslyn 源生成器等工具更新它们。
 
建议希望支持本机 AOT 的库作者:
 
了解本机 AOT 兼容性要求。
准备要剪裁的库。
新建项目模板
新的 ASP.NET Core Web API(本机 AOT)项目模板(简称为 webapiaot)会创建一个启用了 AOT 发布的项目。 有关详细信息,请参阅 Web API(本机 AOT)模板。
 
新的 CreateSlimBuilder 方法
Web API(原生 AOT)模板中使用的 CreateSlimBuilder() 方法通过运行应用所需的最少 ASP.NET Core 功能初始化 WebApplicationBuilder。 CreateSlimBuilder 方法包含高效开发体验通常需要的以下功能:
 
appsettings.json 和 appsettings.{EnvironmentName}.json 的 JSON 文件配置。
用户机密配置。
控制台日志记录。
日志记录配置。
有关详细信息,请参阅 CreateSlimBuilder 方法。
 
新的 CreateEmptyBuilder 方法
还有另一种新的 WebApplicationBuilder 工厂方法(用于构建仅包含必要功能的小型应用):WebApplication.CreateEmptyBuilder(WebApplicationOptions options)。 创建此 WebApplicationBuilder 时没有内置行为。 它生成的应用仅包含显式配置的服务和中间件。
 
下面是一个使用此 API 创建小型 Web 应用程序的示例:
 
C#
 
复制
var builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions());
builder.WebHost.UseKestrelCore();
 
var app = builder.Build();
 
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello, World!");
    await next(context);
});
 
Console.WriteLine("Running...");
app.Run();
在 linux-x64 计算机上使用 .NET 8 Preview 7 通过原生 AOT 发布此代码会生成约 8.5 MB 的独立、原生可执行文件。
 
通过可配置的 HTTPS 支持减小了应用大小
我们进一步减少了不需要 HTTPS 或 HTTP/3 支持的应用的本机 AOT 二进制文件大小。 对于在 TLS 终止代理(例如托管在 Azure 上的代理)后面运行的应用,通常不需要使用 HTTPS 或 HTTP/3。 新的 WebApplication.CreateSlimBuilder 方法默认省略了此功能。 可通过调用 builder.WebHost.UseKestrelHttpsConfiguration()(对于 HTTPS)或 builder.WebHost.UseQuic()(对于 HTTP/3)来添加它。 有关详细信息,请参阅 CreateSlimBuilder 方法。
 
使用拦截器提高性能
请求委托生成器使用新的 C# 12 拦截器编译器功能来支持拦截对最小 API 的 Map 操作方法的调用,在运行时静态生成变体。 使用拦截器可以提高使用 PublishAot 编译的应用的启动性能。
 
编译器生成的 IAsyncEnumerable<T> 类型的 JSON 序列化
向 System.Text.Json 添加了新功能,以更好地支持本机 AOT。 这些新功能为 System.Text.Json 的源生成模式添加了功能,因为 AOT 不支持反射。
 
其中一项新功能是支持对 C# 编译器实现的 IAsyncEnumerable<T> 实现进行 JSON 序列化。 此支持在配置为发布本机 AOT 的 ASP.NET Core 项目中开放了它们的使用。
 
在路由处理程序使用 yield return 异步返回枚举的情况下,此 API 非常有用。 例如,具体化数据库查询的行。 有关详细信息,请参阅 .NET 8 预览版 4 公告中的无法形容的类型支持。
 
有关 System.Text.Json 源生成中其他改进的信息,请参阅 .NET 8 中的序列化改进。
 
为剪裁警告批注的顶级 API
现已批注无法可靠地使用本机 AOT 的子系统的主要入口点。 从启用了本机 AOT 的应用程序调用这些方法时,会提供警告。 例如,以下代码在调用 AddControllers 时生成警告,因为此 API 在剪裁方面不安全,且不受本机 AOT 支持。
 
Visual Studio window showing IL2026 warning message on the AddControllers method that says MVC doesn't currently support native AOT.
 
请求委托生成器
为了使最小 API 与本机 AOT 兼容,我们将引入请求委托生成器 (RDG)。 RDG 是一个源生成器,发挥 RequestDelegateFactory (RDF) 的作用。 也就是说,它将各种 MapGet()、MapPost() 以及这类调用转换为与指定路由关联的 RequestDelegate 实例。 但 RDG 不会在启动时在应用程序的内存中执行此操作,而是会在编译时执行此操作,并将 C# 代码直接生成到项目中。 RDG:
 
去除了在运行时生成此代码的操作。
确保 API 中使用的类型可由本机 AOT 工具链静态分析。
确保必要的代码不会被剪裁掉。
我们正在设法确保 RDG 支持尽可能多的最小 API 功能,以便能与本机 AOT 兼容。
 
当启用了“使用本机 AOT 进行发布”时,会自动在项目中启用 RDG。 即使不使用本机 AOT,也可以通过在项目文件中设置 <EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator> 来手动启用 RDG。 这在最初评估项目对本机 AOT 的就绪情况或需要缩短应用的启动时间时会很有用。
 
编译时生成的最小 API 中的日志记录和异常处理
运行时生成的最小 API 支持在参数绑定失败时自动进行记录(或在开发环境中引发异常)。 .NET 8 引入了对通过请求委托生成器 (RDG) 在编译时生成的 API 的相同支持。 有关详细信息,请参阅编译时生成的最小 API 中的日志记录和异常处理。
 
AOT 和 System.Text.Json
最小 API 经过优化,可更好地使用 JS 接收和返回 System.Text.JsonON 有效负载,因此也适用 JSON 和本机 AOT 的兼容性要求。 本机 AOT 兼容性需要使用 System.Text.Json 源生成器。 在最小 API 中作为请求委托的参数或从请求委托返回的参数而被接受的所有类型都必须在通过 ASP.NET Core 的依赖项注入注册的 JsonSerializerContext 上进行配置,例如:
 
C#
 
复制
// Register the JSON serializer context with DI
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
 
...
 
// Add types used in the minimal API app to source generated JSON serializer content
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
 
}
有关 TypeInfoResolverChain API 的详细信息,请参阅下列资源:
 
JsonSerializerOptions.TypeInfoResolverChain
链接源生成器
支持源生成的更改
库和本机 AOT
目前许多可用于 ASP.NET Core 项目的通用库如果在面向本机 AOT 的项目中使用,会有一些兼容性问题。 常用库通常依赖于 .NET 反射的动态功能来检查和发现类型,会在运行时有条件地加载库,并动态生成代码以实现其功能。 这些库需要进行更新,以便使用 Roslyn 源生成器等工具处理本机 AOT。
 
对于希望详细了解如何让库为本机 AOT 做准备的库作者,建议首先让库做好剪裁的准备,并详细了解本机 AOT 兼容性要求。
 
Kestrel 和 HTTP.sys 服务器
Kestrel 和 HTTP.sys 有几个新功能。
 
对 Kestrel 中命名管道的支持
命名管道是一种用于生成 Windows 应用间的进程间通信 (IPC) 的常用技术。 现在可以使用 .NET、Kestrel 和命名管道生成 IPC 服务器。
 
C#
 
复制
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenNamedPipe("MyPipeName");
});
有关此功能以及如何使用 .NET 和 gRPC 创建 IPC 服务器和客户端的详细信息,请参阅与 gRPC 的进程间通信。
 
命名管道传输的性能改进
我们改进了命名管道的连接性能。 Kestrel 的命名管道传输现在接受并行连接,并会重复使用 NamedPipeServerStream 实例。
 
创建 100,000 个连接的时间:
 
之前:5.916 秒
之后:2.374 秒
Kestrel 中 macOS 上的 HTTP/2 over TLS (HTTPS) 支持
.NET 8 向 macOS 添加了对应用程序层协议协商 (ALPN) 的支持。 ALPN 是一项 TLS 功能,用于协商连接将使用的 HTTP 协议。 例如,ALPN 允许浏览器和其他 HTTP 客户端请求 HTTP/2 连接。 此功能对于需要 HTTP/2 的 gRPC 应用特别有用。 有关详细信息,请参阅对 ASP.NET Core Kestrel Web 服务器使用 HTTP/2。
 
不使用指定的 HTTP 协议时发出警告
如果 TLS 已被禁用而 HTTP/1.x 可用,则 HTTP/2 和 HTTP/3 都将被禁用,即使已指定这二者。 这可能会导致发生一些不好的意外情况,因此我们添加了警告输出,以便在发生这种情况时通知你。
 
HTTP_PORTS 和 HTTPS_PORTS 配置密钥
应用程序和容器通常只能侦听一个端口(比如端口 80),且没有其他限制(比如主机或路径)。 HTTP_PORTS 和 HTTPS_PORTS 是允许为 Kestrel 和 HTTP.sys 服务器指定侦听端口的新配置密钥。 可以使用 DOTNET_ 或 ASPNETCORE_ 环境变量前缀定义这些密钥,也可以直接通过任何其他配置输入(例如 appsettings.json)指定这些密钥。 每个密钥都是一个以分号分隔的端口值列表。 例如:
 
cli
 
复制
ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081
这是以下项的简写,它指定了方案(HTTP 或 HTTPS)和任何主机或 IP:
 
cli
 
复制
ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/
有关详细信息,请参阅为 ASP.NET Core Kestrel Web 服务器配置终结点和在 ASP.NET Core 中的 HTTP.sys Web 服务器实现。
 
ITlsHandshakeFeature 中的 SNI 主机名
现在,服务器名称指示器 (SNI) 主机名已在 ITlsHandshakeFeature 接口的HostName 属性中公开。
 
SNI 是 TLS 握手过程的一部分。 它允许客户端在服务器托管多个虚拟主机或域时指定尝试连接的主机名。 要在握手过程中提供正确的安全证书,服务器需要知道为每个请求选择的主机名。
 
通常,主机名仅在 TLS 堆栈中处理,并用于选择匹配的证书。 但通过公开它,应用中的其他组件可以将该信息用于诊断、速率限制、路由和计费等目的。
 
公开主机名对于管理数千个 SNI 绑定的大规模服务很有用。 此功能可以在客户升级期间显著提高调试效率。 通过提高透明度,可以更快地解决问题和提高服务可靠性。
 
有关详细信息,请参阅 ITlsHandshakeFeature.HostName。
 
IHttpSysRequestTimingFeature
在使用 HTTP.sys 服务器和 IIS 进程内托管时,IHttpSysRequestTimingFeature 用于为请求提供详细的时间信息:
 
使用 QueryPerformanceCounter 获取时间戳。
可通过 QueryPerformanceFrequency 获取时间戳频率。
时间索引可强制转换为 HttpSysRequestTimingType,这样便可知道时间的具体内容。
如果时间不适用于当前请求,该值可能为 0。
IHttpSysRequestTimingFeature.TryGetTimestamp 可检索提供的时间类型的时间戳:
 
C#
 
复制
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
 
builder.WebHost.UseHttpSys();
 
var app = builder.Build();
 
app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
 
    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");
 
    var timingType = HttpSysRequestTimingType.RequestRoutingEnd;
 
    if (feature.TryGetTimestamp(timingType, out var timestamp))
    {
        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }
    else
    {
        logger.LogInformation("Timestamp {timingType}: not available for the "
                                           + "current request",    timingType);
    }
 
    return next(context);
});
 
app.MapGet("/", () => Results.Ok());
 
app.Run();
有关详细信息,请参阅使用 IHttpSysRequestTimingFeature 获取详细的时间信息以及 IIS 进程内托管。
 
HTTP.sys:选择加入对内核模式响应缓冲的支持
在某些场景下,高延迟的大量小型写入可能会对 HTTP.sys 造成重大的性能影响。 这种影响是由于 HTTP.sys 实现中缺少 Pipe 缓冲区导致的。 为了在这些方案中提高性能,已向 HTTP.sys 添加对响应缓冲的支持。 通过将 HttpSysOptions.EnableKernelResponseBuffering 设置为 true 来启用缓冲。
 
响应缓冲应由执行同步 I/O 或异步 I/O 且一次不超过一个未完成写入的应用来启用。 在这些方案中,响应缓冲可以在高延迟连接上显著提高吞吐量。
 
使用异步 I/O 且一次可能有多个未完成的写入的应用不应使用此标志。 通过 HTTP.Sys 启用此标志可能会导致 CPU 和内存使用率升高。
 
身份验证和授权
ASP.NET Core 8 为身份验证和授权添加了新功能。
 
Identity API 终结点
MapIdentityApi<TUser> 是一种新的扩展方法,用于添加两个 API 终结点(/register 和 /login)。 MapIdentityApi 的主要目的是为了让开发人员能够轻松使用 ASP.NET Core Identity 在基于 JavaScript 的单页应用 (SPA) 或 Blazor 应用中进行身份验证。 MapIdentityAPI 没有使用 ASP.NET Core Identity 提供的基于 Razor Pages 的默认 UI,而是添加了更适合 SPA 应用和非浏览器应用的 JSON API 终结点。 有关详细信息,请参阅Identity API 终结点。
 
IAuthorizationRequirementData
在 ASP.NET Core 8 之前的版本中,将参数化授权策略添加到终结点需要:
 
为每个策略实现 AuthorizeAttribute。
实现 AuthorizationPolicyProvider 以处理基于字符串的协定中的自定义策略。
为策略实现 AuthorizationRequirement。
为每个要求实现 AuthorizationHandler。
例如,来看看为 ASP.NET Core 7.0 编写的以下示例:
 
C#
 
复制
using AuthRequirementsData.Authorization;
using Microsoft.AspNetCore.Authorization;
 
var builder = WebApplication.CreateBuilder();
 
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddControllers();
builder.Services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();
 
var app = builder.Build();
 
app.MapControllers();
 
app.Run();
C#
 
复制
using Microsoft.AspNetCore.Mvc;
 
namespace AuthRequirementsData.Controllers;
 
[ApiController]
[Route("api/[controller]")]
public class GreetingsController : Controller
{
    [MinimumAgeAuthorize(16)]
    [HttpGet("hello")]
    public string Hello() => $"Hello {(HttpContext.User.Identity?.Name ?? "world")}!";
}
C#
 
复制
using Microsoft.AspNetCore.Authorization;
using System.Globalization;
using System.Security.Claims;
 
namespace AuthRequirementsData.Authorization;
 
class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeRequirement>
{
    private readonly ILogger<MinimumAgeAuthorizationHandler> _logger;
 
    public MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
    {
        _logger = logger;
    }
 
    // Check whether a given MinimumAgeRequirement is satisfied or not for a particular
    // context.
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                               MinimumAgeRequirement requirement)
    {
        // Log as a warning so that it's very clear in sample output which authorization
        // policies(and requirements/handlers) are in use.
        _logger.LogWarning("Evaluating authorization requirement for age >= {age}",
                                                                    requirement.Age);
 
        // Check the user's age
        var dateOfBirthClaim = context.User.FindFirst(c => c.Type ==
                                                                 ClaimTypes.DateOfBirth);
        if (dateOfBirthClaim != null)
        {
            // If the user has a date of birth claim, check their age
            var dateOfBirth = Convert.ToDateTime(dateOfBirthClaim.Value, CultureInfo.InvariantCulture);
            var age = DateTime.Now.Year - dateOfBirth.Year;
            if (dateOfBirth > DateTime.Now.AddYears(-age))
            {
                // Adjust age if the user hasn't had a birthday yet this year.
                age--;
            }
 
            // If the user meets the age criterion, mark the authorization requirement
            // succeeded.
            if (age >= requirement.Age)
            {
                _logger.LogInformation("Minimum age authorization requirement {age} satisfied",
                                         requirement.Age);
                context.Succeed(requirement);
            }
            else
            {
                _logger.LogInformation("Current user's DateOfBirth claim ({dateOfBirth})" +
                    " does not satisfy the minimum age authorization requirement {age}",
                    dateOfBirthClaim.Value,
                    requirement.Age);
            }
        }
        else
        {
            _logger.LogInformation("No DateOfBirth claim present");
        }
 
        return Task.CompletedTask;
    }
}
完整示例位于 AspNetCore.Docs.Samples 存储库中的此处。
 
ASP.NET Core 8 引入了 IAuthorizationRequirementData 接口。 IAuthorizationRequirementData 接口允许属性定义指定与授权策略关联的要求。 使用 IAuthorizationRequirementData,可以使用更少的代码行编写前面的自定义授权策略代码。 已更新的 Program.cs 文件:
 
diff
 
复制
  using AuthRequirementsData.Authorization;
  using Microsoft.AspNetCore.Authorization;
  
  var builder = WebApplication.CreateBuilder();
  
  builder.Services.AddAuthentication().AddJwtBearer();
  builder.Services.AddAuthorization();
  builder.Services.AddControllers();
- builder.Services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
  builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();
  
  var app = builder.Build();
  
  app.MapControllers();
  
  app.Run();
已更新的 MinimumAgeAuthorizationHandler:
 
diff
 
复制
using Microsoft.AspNetCore.Authorization;
using System.Globalization;
using System.Security.Claims;
 
namespace AuthRequirementsData.Authorization;
 
- class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeRequirement>
+ class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeAuthorizeAttribute>
{
    private readonly ILogger<MinimumAgeAuthorizationHandler> _logger;
 
    public MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
    {
        _logger = logger;
    }
 
    // Check whether a given MinimumAgeRequirement is satisfied or not for a particular
    // context
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
-                                              MinimumAgeRequirement requirement)
+                                              MinimumAgeAuthorizeAttribute requirement)
    {
        // Remaining code omitted for brevity.
可以在此处找到完整的更新示例。
 
有关新示例的详细说明,请参阅使用 IAuthorizationRequirementData 自定义授权策略。
 
保护 Swagger UI 终结点
现在,可以通过调用 MapSwagger().RequireAuthorization 在生产环境中保护 Swagger UI 终结点。 有关详细信息,请参阅保护 Swagger UI 终结点
 
其他
以下各节介绍 ASP.NET Core 8 中的其他新功能。
 
依赖项注入中的键控服务支持
密钥服务是指使用密钥注册和检索依赖项注入 (DI) 服务的机制。 通过调用 AddKeyedSingleton (或 AddKeyedScoped 或 AddKeyedTransient)来注册服务,与密钥相关联。 使用 [FromKeyedServices] 属性指定密钥来访问已注册的服务。 以下代码演示如何使用键化服务:
 
C#
 
复制
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
 
var builder = WebApplication.CreateBuilder(args);
 
builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");
builder.Services.AddControllers();
 
var app = builder.Build();
 
app.MapGet("/big", ([FromKeyedServices("big")] ICache bigCache) => bigCache.Get("date"));
app.MapGet("/small", ([FromKeyedServices("small")] ICache smallCache) =>
                                                               smallCache.Get("date"));
 
app.MapControllers();
 
app.Run();
 
public interface ICache
{
    object Get(string key);
}
public class BigCache : ICache
{
    public object Get(string key) => $"Resolving {key} from big cache.";
}
 
public class SmallCache : ICache
{
    public object Get(string key) => $"Resolving {key} from small cache.";
}
 
[ApiController]
[Route("/cache")]
public class CustomServicesApiController : Controller
{
    [HttpGet("big-cache")]
    public ActionResult<object> GetOk([FromKeyedServices("big")] ICache cache)
    {
        return cache.Get("data-mvc");
    }
}
 
public class MyHub : Hub
{
    public void Method([FromKeyedServices("small")] ICache cache)
    {
        Console.WriteLine(cache.Get("signalr"));
    }
}
适用于具有 ASP.NET 核心后端的 SPA 应用的 Visual Studio 项目模板
Visual Studio 项目模板现在是推荐用于创建具有 ASP.NET 核心后端的单页应用 (SPA) 的方法。 提供了基于 JavaScript 框架 Angular、React 和 Vue 创建应用的模板。 这些模板:
 
创建一个包含前端项目和后端项目的 Visual Studio 解决方案。
将 Visual Studio 项目类型用于 JavaScript,将 TypeScript (.esproj) 用于前端。
将 ASP.NET Core 项目用于后端。
有关 Visual Studio 模板以及如何访问旧模板的详细信息,请参阅 ASP.NET Core 中的单页应用 (SPA) 概述
 
对泛型属性的支持
以前需要 Type 参数的属性现在可采用更简洁的泛型变体。 这可以通过支持 C# 11 中的泛型属性来实现。 例如,可以按以下所示修改用于注释操作响应类型的语法:
 
diff
 
复制
[ApiController]
[Route("api/[controller]")]
public class TodosController : Controller
{
  [HttpGet("/")]
- [ProducesResponseType(typeof(Todo), StatusCodes.Status200OK)]
+ [ProducesResponseType<Todo>(StatusCodes.Status200OK)]
  public Todo Get() => new Todo(1, "Write a sample", DateTime.Now, false);
}
支持以下属性的泛型变体:
 
[ProducesResponseType<T>]
[Produces<T>]
[MiddlewareFilter<T>]
[ModelBinder<T>]
[ModelMetadataType<T>]
[ServiceFilter<T>]
[TypeFilter<T>]
ASP.NET Core 应用中的代码分析
下表中显示的新分析器在 ASP.NET Core 8.0 中可用。
 
诊断 ID 中断性或非中断性 说明
ASP0016 非中断性 不从 RequestDelegate 返回值
ASP0019 非中断性 建议使用 IHeaderDictionary.Append 或索引器
ASP0020 非中断性 路由参数引用的复杂类型必须是可分析的
ASP0021 非中断性 BindAsync 方法的返回类型必须为 ValueTask<T>
ASP0022 非中断性 检测到路由处理程序之间的路由冲突
ASP0023 非中断性 MVC:检测到路由处理程序之间的路由冲突
ASP0024 非中断性 路由处理程序具有包含 [FromBody] 属性的多个参数
ASP0025 非中断性 使用 AddAuthorizationBuilder
路由工具
ASP.NET Core 的构建基于路由。 最小 API、Web API、Razor Pages 和 Blazor 都使用路由来自定义 HTTP 请求映射到代码的方式。
 
在 .NET 8 中,我们引入了一套新功能,可使路由更易于被了解和使用。 这些新功能包括:
 
路由语法重点内容
自动完成参数和路由名称
自动完成路由约束
路由分析器和修复器
路由语法分析器
不匹配的参数可选性分析器和修复器
不明确的最小 API 和 Web API 路由分析器
对最小 API、Web API 和 Blazor 的支持
有关详细信息,请参阅 .NET 8 中的路由工具。
 
ASP.NET Core 指标
指标是指在一段时间内报告的度量值,通常用于监视应用的运行状况以及生成警报。 例如,报告 HTTP 请求失败的计数器可以显示在仪表板中,或者在失败超过阈值时生成警报。
 
此预览版使用 System.Diagnostics.Metrics 在整个 ASP.NET Core 中添加了新指标。 Metrics 是用于报告和收集有关应用信息的新式 API。
 
与现有事件计数器相比,指标提供了许多改进:
 
包含计数器、仪表和直方图的新度量类型。
包含多维值的功能强大的报告。
通过与 OpenTelemetry 标准保持一致,可集成到更广泛的云原生生态系统中。
ASP.NET Core 托管 Kestrel 和 SignalR 中已添加指标。 有关详细信息,请参阅 System.Diagnostics.Metrics。
 
IExceptionHandler
IExceptionHandler 是一个新接口,可为开发人员提供用于在中心位置处理已知异常的回叫。
 
IExceptionHandler 实现是通过调用 IServiceCollection.AddExceptionHandler<T> 来注册的。 可以添加多个实现,并按注册顺序调用它们。 如果异常处理程序处理请求,它可以返回 true 来停止处理。 如果异常不是由任何异常处理程序处理,则控件将回退到中间件的默认行为和选项。
 
有关详细信息,请参阅 IExceptionHandler。
 
改善了调试体验
调试自定义属性已添加到 HttpContext、HttpRequest、HttpResponse、ClaimsPrincipal 和 WebApplication 等类型。 针对这些类型的增强型调试程序显示使你可以更轻松地在 IDE 调试程序中查找重要信息。 以下屏幕截图显示了这些属性给调试程序显示的 HttpContext 带来的差异。
 
.NET 7:
 
Unhelpful debugger display of HttpContext type in .NET 7.
 
.NET 8:
 
Helpful debugger display of HttpContext type in .NET 8.
 
WebApplication 的调试器显示突出显示了重要信息,例如配置的终结点、中间件和 IConfiguration 值。
 
.NET 7:
 
Unhelpful debugger display of WebApplication type in .NET 7.
 
.NET 8:
 
Helpful debugger display of WebApplication type in .NET 8.
 
有关 .NET 8 中调试改进的详细信息,请参阅 GitHub 问题 dotnet/aspnetcore 48205。
 
IPNetwork.Parse 和 TryParse
IPNetwork 上新的 Parse 和 TryParse 方法增加了对使
软件无法下载?不知道解压密码?微信关注订阅号"闪电下载"获取

本帖长期更新最新版 请收藏下载!版权声明:本站提的序列号、注册码、注册机、破解补丁等均来自互联网,仅供学习交流之用,请在下载后24小时内删除。

  • 下载地址

捐助vip:软件无法下载?联系:sd173@foxmail.com

  • 猜你喜欢
  • 用户评论