资讯动态

实战解析:在 ASP.NET Core 中间件中通过 IEndpointFeature 获取当前 Endpoint 信息

发布时间:2026/10/15 12:18:02 来源:尧图企业网站定制
示例工程【免费下载链接】practical-aspnetcorePractical samples of ASP.NET Core 11, 10, 9, 8.0, 7.0, 6.0, 5.0, 3.1, 2.2, and 2.1,projects you can use. Readme contains explanations on all projects.项目地址https://gitcode.com/gh_mirrors/pr/practical-aspnetcore点击查看免费下载本文围绕practical-aspnetcore仓库中的 new-routing-14 示例讲解如何在 ASP.NET Core 端点路由Endpoint Routing体系下通过HttpContext.Features.GetIEndpointFeature()读取当前正在执行的Endpoint对象并对比其与HttpContext.GetEndpoint()两种写法的关系。读完本文你将掌握在自定义中间件或内联处理逻辑中获取当前端点名称、元数据等信息的两种途径并能结合Endpoint.Metadata与WithMetadata实现更丰富的端点信息利用。背景端点路由中的 Endpoint 抽象自 ASP.NET Core 3.0 引入端点路由以来路由匹配的产物不再是传统的路由表 执行委托而是一个统一抽象的Endpoint对象。一个Endpoint描述了某条路由对应的处理程序以及附加在该路由上的元数据Metadata例如授权要求、CORS 策略、自定义特性等。在 MVC、Razor Pages、最小 API 等框架之上端点路由把匹配与执行分离先由路由中间件完成匹配并选定Endpoint随后再由后续中间件如授权中间件或终端中间件如 MVC 的执行器基于该Endpoint决定如何处理请求。因此在自定义中间件里知道当前请求命中了哪个端点是一项很常见的能力需求。仓库的 endpoint-routing 总览 中收录了从路由映射、元数据读取、动态路由到 Host 匹配等 32 个相关示例而本示例new-routing-14聚焦的是获取端点这一底层机制本身。核心示例通过 IEndpointFeature 读取 Endpointnew-routing-14 的 Program.cs 是完整的可运行示例其核心只有寥寥数行using Microsoft.AspNetCore.Http.Features; var builder WebApplication.CreateBuilder(); builder.Services.AddControllersWithViews(); var app builder.Build(); app.MapGet(/, async context { var feature context.Features.GetIEndpointFeature(); await context.Response.WriteAsync($Endpoint Name {feature.Endpoint.DisplayName}); }); app.Run();这段代码的关键点在以下三处using Microsoft.AspNetCore.Http.Features;Program.cs 第 1 行IEndpointFeature接口定义在该命名空间下。context.Features.GetIEndpointFeature()Program.cs 第 10 行通过HttpContext.Features特性集合按接口类型取回端点特性对象。feature.Endpoint.DisplayNameProgram.cs 第 11 行从特性对象上拿到Endpoint并输出其DisplayName。当访问根路径/时浏览器会收到类似Endpoint Name HTTP: GET /的输出——DisplayName是端点路由为每个端点生成的、便于日志与调试识别的名称。IEndpointFeature 是什么IEndpointFeature是一个专门承载当前端点的 Feature 接口它暴露了一个Endpoint Endpoint { get; }属性。ASP.NET Core 的特性Feature机制允许服务器与中间件在HttpContext.Features集合中按接口类型注册/取出运行时数据而IEndpointFeature正是端点路由中间件在执行时写入该集合的信号。从代码结构看可以推断路由匹配完成后框架会把选中的Endpoint包装进IEndpointFeature放入Features集合后续任何中间件都能按需取回。这种通过接口查询特性的方式与HttpContext.Items这类字典式存取相比类型更明确、职责更单一。等效写法HttpContext.GetEndpoint()示例 README 明确指出HttpContext.GetEndpoint()可以达到同样的效果You can accomplish the same thing usingHttpContext.GetEndpoint.GetEndpoint()是定义在HttpContext上的扩展方法其内部本质上就是对Features.GetIEndpointFeature()的封装并额外处理了未启用端点路由 / 尚未匹配时返回null的情况。两种写法的对比如下维度Features.GetIEndpointFeature()HttpContext.GetEndpoint()访问方式直接访问HttpContext.Features特性集合调用HttpContext的扩展方法可读性偏底层、机制导向更直观、语义清晰空值处理需自行判空路由未匹配时集合中无该特性返回Endpoint或null同样需判空适用场景想显式表达我在读端点特性或需要同时接触其他 Feature绝大多数日常开发场景仓库中的配套示例大量采用了GetEndpoint()写法例如 new-routing-10 的自定义中间件、new-routing-13 的 MVC 元数据读取均先通过httpContext.GetEndpoint()拿到端点对象。因此可以认为GetEndpoint()是日常推荐写法而Features.GetIEndpointFeature()是理解其底层原理的钥匙。两个容易忽略的要点判空必不可少无论是哪种写法在路由匹配尚未发生的阶段例如UseRouting()之前的中间件IEndpointFeature尚未写入特性集合此时GetEndpoint()会返回null直接访问feature.Endpoint则会抛出空引用异常。因此在实际中间件代码中应先判断端点是否存在。DisplayName之外还有 MetadataEndpoint对象的另一重要成员是Metadata集合。下面会看到如何通过它与WithMetadata配合把信息从端点传递给中间件。实战扩展一在自定义中间件中根据 DisplayName 分流如果把示例中的内联处理逻辑迁移到类形式的中间件并结合仓库 new-routing-10 的写法就得到了中间件感知端点的典型模式public class GreeterMiddleware { RequestDelegate _next; public GreeterMiddleware(RequestDelegate next) { _next next; } public async Task InvokeAsync(HttpContext httpContext) { Endpoint endPoint httpContext.GetEndpoint(); if (endPoint ! null endPoint.DisplayName /about) { httpContext.Items.Add(GreetingFromMiddleWare, Hello world from GreetingMiddleware); } await _next.Invoke(httpContext); } }在 new-routing-10 中中间件正是通过比较DisplayName来决定是否为请求注入问候语从而验证了路由匹配结果可以在执行链中任意中间件内被读取这一设计意图。实战扩展二从 Endpoint.Metadata 中读取自定义特性端点对象的价值不止于名称更在于元数据。仓库的 new-routing-13 展示了在 MVC 场景下中间件如何读取控制器/动作方法上标注的自定义特性Endpoint endPoint httpContext.GetEndpoint(); var message endPoint.Metadata.GetMetadataMessageAttribute(); if (message ! null) httpContext.Items.Add(GreetingFromMiddleWare, message.Content);这里的Endpoint.Metadata.GetMetadataT()会在端点的元数据集合中查找类型为T的元数据项找不到时返回null而非抛异常因此先判空再使用是安全做法。把本节与上一节组合起来一个中间件就能做到识别端点身份 读取端点携带的策略/文案信息这正是端点路由替代旧式UseMvc管线后中间件协作的核心姿势。实战扩展三用 WithMetadata 为内联端点附加元数据如果说读取元数据是取那么 new-routing-15 则展示了给的一面——用IEndpointConventionBuilder.WithMetadata为内联端点挂上自定义元数据app.MapGet(/, async context { var endpoint context.GetEndpoint(); var greeting endpoint.Metadata.GetMetadataHelloWorld(); await context.Response.WriteAsync($Greeting from metadata : {greeting.Greeting}); }).WithMetadata(new HelloWorld { Greeting Hello World }); public class HelloWorld { public string Greeting { get; set; } }可以看到WithMetadata在定义端点时就把HelloWorld实例附加进去而请求处理时再通过GetMetadataHelloWorld()取回。将 new-routing-14 的获取机制与WithMetadata组合即可实现端点自带配置、中间件按需消费的完整闭环。运行方式与项目结构示例项目本身非常精简便于直接运行验证项目文件new-routing-14.csproj目标框架为net10.0启用隐式 using 与预览语言特性LangVersion为preview。源码文件Program.cs。说明文档README.md。在项目目录下执行dotnet run随后访问http://localhost:5000或dotnet run输出中显示的 URL即可看到页面输出当前端点的DisplayName。读者可自行将MapGet(/, ...)中的内联逻辑替换为上文的自定义中间件版本体验两种获取方式的等价性。小结HttpContext.Features.GetIEndpointFeature()是端点路由在Features集合中暴露当前端点的底层机制new-routing-14 示例 给出了最简可运行的演示。HttpContext.GetEndpoint()是其便捷封装功能等价、写法更直观是中间件与内联处理中读取端点的推荐入口。拿到Endpoint后DisplayName用于识别端点身份参考 new-routing-10Metadata.GetMetadataT()用于读取自定义元数据参考 new-routing-13而WithMetadata则用于在定义端点时附加元数据参考 new-routing-15。无论采用哪种方式都要牢记在路由匹配之前端点可能为null务必判空后再访问端点属性。赞分享示例工程【免费下载链接】practical-aspnetcorePractical samples of ASP.NET Core 11, 10, 9, 8.0, 7.0, 6.0, 5.0, 3.1, 2.2, and 2.1,projects you can use. Readme contains explanations on all projects.项目地址https://gitcode.com/gh_mirrors/pr/practical-aspnetcore点击查看免费下载相关推荐ASP.NET Core 中的 WebSockets 实战中间件、握手与全双工实时通信ASP.NET Core 中的 WebSockets 实战中间件、握手与全双工实时通信 WebSockets 是 ASP.NET Core 实时通信能力的基础文档教程知识库FastAPI-Users项目实战如何获取当前用户信息FastAPI Users项目实战如何获取当前用户信息 引言 在Web应用开发中用户认证是基础而重要的功能。FastAPI Users作为FastAPI生态后端认证鉴权Web框架MouseTracks项目在Linux系统中获取当前焦点窗口信息的实现方法MouseTracks项目在Linux系统中获取当前焦点窗口信息的实现方法 在开发桌面应用时经常需要获取当前获得焦点的窗口信息。MouseTracks项目最创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑