.NET 6 Minimal Web API如何定义包含冒号的路由?
在.NET 6 Minimal Web API中让冒号成为路由定义的一部分
问题描述
我创建了一个.NET 6 Minimal Web API,需要支持特定格式的URL(例如/sensor/sensor:123/measurement)。最初的代码如下:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.MapGet("/sensor/sensor:{sensorId}/measurement", (int sensorId) => { return Results.Ok(); }); app.Run();
但运行后Swagger UI中显示的GET URL为/sensor/sensor}/measurement,实际调用时返回404错误。虽然修改为以下代码可以正常运行,但需要额外的字符串解析逻辑,我希望冒号能直接作为路由定义的一部分:
app.MapGet("/sensor/sensor{sensorId}/measurement", (string sensorId) => { // 需要额外解析sensorId,提取冒号后的数字 return Results.Ok(); });
解决方案
要让冒号成为路由定义的一部分并正确绑定参数,只需在路由参数后明确指定类型约束,这样.NET路由解析器就能正确区分字面量冒号和参数部分。
修改后的代码如下:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } // 在参数sensorId后添加:int约束,明确参数类型 app.MapGet("/sensor/sensor:{sensorId:int}/measurement", (int sensorId) => { return Results.Ok(new { SensorId = sensorId }); }); app.Run();
原理说明
在.NET路由模板中,冒号:是路由参数与其约束(如类型、正则规则)的分隔符。当你仅写{sensorId}而未指定约束时,路由解析器会错误地将冒号后的内容识别为未完成的约束定义,导致Swagger生成错误的URL,同时实际请求无法匹配路由。
通过添加:int类型约束,解析器会正确识别:
sensor:是路由中的字面量部分{sensorId:int}是绑定到int类型的路由参数
这样既无需额外解析字符串,Swagger也能正确生成/sensor/sensor:{sensorId}/measurement的URL,请求/sensor/sensor:123/measurement时可以直接获取到sensorId=123的值。
内容的提问来源于stack exchange,提问作者James Skemp
相关产品推荐
相关产品推荐

