ASP.NET Core 7 WebApi中如何获取RouteGroupBuilder的路由组前缀?
.NET 7 获取路由组前缀的正确方法
.NET 7引入的路由组(Route Groups)允许通过公共前缀对端点进行分组,比如:
app.MapGroup("/public/todos").MapTodosApi();
你提到官方文档提及用GroupRouteBuilder.GroupPrefix构造201 Created响应的Location绝对路径,但实际不存在GroupRouteBuilder类,且RouteGroupBuilder也没有GroupPrefix成员。这是官方文档的笔误,以下是几种正确获取路由组前缀的方式:
方法一:定义路由组时显式传递前缀
在创建路由组时直接保存前缀,传递给扩展方法或服务,这种方式简单直观:
// 扩展方法接收前缀参数 public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group, string groupPrefix) { group.MapPost("/", async (Todo todo, IHttpContextAccessor accessor) => { var createdTodo = await _todoService.Create(todo); // 构造绝对URI var absoluteUri = new Uri($"{accessor.HttpContext.Request.Scheme}://{accessor.HttpContext.Request.Host}{groupPrefix}/{createdTodo.Id}"); return Results.Created(absoluteUri, createdTodo); }); return group; } // 使用时传入前缀 var todosPrefix = "/public/todos"; app.MapGroup(todosPrefix).MapTodosApi(todosPrefix);
方法二:从RouteGroupBuilder的元数据中提取
RouteGroupBuilder的元数据集合中包含RouteGroupMetadata,可以从中获取分组前缀:
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group) { // 获取路由组元数据 var groupMetadata = group.Metadata.OfType<RouteGroupMetadata>().FirstOrDefault(); var groupPrefix = groupMetadata?.Prefix ?? string.Empty; group.MapPost("/", async (Todo todo, IHttpContextAccessor accessor) => { var createdTodo = await _todoService.Create(todo); var absoluteUri = new Uri($"{accessor.HttpContext.Request.Scheme}://{accessor.HttpContext.Request.Host}{groupPrefix}/{createdTodo.Id}"); return Results.Created(absoluteUri, createdTodo); }); return group; }
方法三:从当前端点的元数据中解析前缀
如果需要在单个端点内获取完整路由前缀,可以通过HttpContext的端点元数据解析:
group.MapPost("/", async (Todo todo, HttpContext context) => { var routePatternMetadata = context.GetEndpoint()?.Metadata.OfType<RoutePatternMetadata>().FirstOrDefault(); if (routePatternMetadata?.RoutePattern == null) { return Results.BadRequest(); } // 提取路由前缀部分 var routeParts = routePatternMetadata.RoutePattern.RawText.Split('/').ToList(); var idIndex = routeParts.IndexOf("{id}"); var groupPrefix = idIndex > 0 ? string.Join("/", routeParts.Take(idIndex)) : string.Empty; var createdTodo = await _todoService.Create(todo); var absoluteUri = new Uri($"{context.Request.Scheme}://{context.Request.Host}/{groupPrefix}/{createdTodo.Id}"); return Results.Created(absoluteUri, createdTodo); });
补充说明
官方文档中提到的GroupRouteBuilder是笔误,正确的类型是RouteGroupBuilder,且需要通过RouteGroupMetadata来获取分组前缀,而非直接访问不存在的GroupPrefix属性。
内容的提问来源于stack exchange,提问作者Dynalon
相关产品推荐
相关产品推荐

