ASP.NET Web API (.NET Core 3.1) 中的端点路由问题
Problem with endpoint routing in ASP.NET Web API (.NET Core 3.1)
下午好,
我在使用属性路由和 ASP.NET 核心路由中间件 API 的网络 API 中遇到端点路由问题。
我有一个 API 控制器,大致如下所示:
public class UsersController : ControllerBase
{
[HttpGet]
[Route("v1/users/{id}", Name = nameof(GetUser), Order = 1)]
public async Task<ActionResult> GetUser([FromQuery(Name = "id")] string userGuid)
{
// Implementation omitted.
}
[HttpGet]
[Route("v1/users/me", Name = nameof(GetCurrentUser), Order = 0)]
public async Task<ActionResult> GetCurrentUser()
{
// Implementation omitted.
}
}
我正在尝试配置端点路由,以便将 'v1/users/me' 的请求路由到 'GetCurrentUser()' 方法,同时请求匹配模板 'v1/users/{id}'(其中 {id} != me) 被路由到 'GetUser()' 方法。我希望这可以通过将 'v1/users/me' 端点放在端点顺序中的另一个端点之前来解决,但路由中间件似乎不遵守顺序参数。我还尝试在映射其余端点之前显式映射 'v1/users/me' 端点,但这似乎也不起作用。
这是当前的启动配置:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseResponseCompression();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
// Explicit mapping of the GetCurrentUser endpoint - doesn't seem to do anything.
// endpoints.MapControllerRoute("v1/users/me", "Users/GetCurrentUser");
endpoints.MapControllers();
}
}
这是否可以通过属性路由实现,如果可以,我还缺少什么?
谢谢!
如果您像这样保留默认值,这应该已经可以正常工作了:
[HttpGet("v1/users/{id}")]
public async Task<ActionResult> GetUser(string id)
{
return Ok(new { id = id });
}
[HttpGet("v1/users/me")]
public async Task<ActionResult> GetCurrentUser()
{
return Ok(new { id = "current" });
}
使用属性路由,包含 constant 部分的路由优于在同一位置包含路由变量的路由。因此 v1/users/me
的排名高于 v1/users/{id}
和 id = "me"
,因此当您访问该路由时,您应该看到 GetCurrentUser
运行。这与控制器中的方法顺序无关。
问题出在 API 端点方法的注释上。
我错误地将 GetUser(string id) 端点中的参数标记为 [FromQuery] 属性而不是 [FromRoute]。
以下按预期工作:
public class UsersController : ControllerBase
{
[HttpGet]
[Route("v1/users/{id}", Name = nameof(GetUser))]
public async Task<ActionResult> GetUser([FromRoute(Name = "id")] string userGuid)
{
// Changed from [FromQuery(Name = "id")] to [FromRoute(Name = "id")]
// Implementation omitted.
}
[HttpGet]
[Route("v1/users/me", Name = nameof(GetCurrentUser))]
public async Task<ActionResult> GetCurrentUser()
{
// Implementation omitted.
}
}
下午好,
我在使用属性路由和 ASP.NET 核心路由中间件 API 的网络 API 中遇到端点路由问题。
我有一个 API 控制器,大致如下所示:
public class UsersController : ControllerBase
{
[HttpGet]
[Route("v1/users/{id}", Name = nameof(GetUser), Order = 1)]
public async Task<ActionResult> GetUser([FromQuery(Name = "id")] string userGuid)
{
// Implementation omitted.
}
[HttpGet]
[Route("v1/users/me", Name = nameof(GetCurrentUser), Order = 0)]
public async Task<ActionResult> GetCurrentUser()
{
// Implementation omitted.
}
}
我正在尝试配置端点路由,以便将 'v1/users/me' 的请求路由到 'GetCurrentUser()' 方法,同时请求匹配模板 'v1/users/{id}'(其中 {id} != me) 被路由到 'GetUser()' 方法。我希望这可以通过将 'v1/users/me' 端点放在端点顺序中的另一个端点之前来解决,但路由中间件似乎不遵守顺序参数。我还尝试在映射其余端点之前显式映射 'v1/users/me' 端点,但这似乎也不起作用。
这是当前的启动配置:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseResponseCompression();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
// Explicit mapping of the GetCurrentUser endpoint - doesn't seem to do anything.
// endpoints.MapControllerRoute("v1/users/me", "Users/GetCurrentUser");
endpoints.MapControllers();
}
}
这是否可以通过属性路由实现,如果可以,我还缺少什么?
谢谢!
如果您像这样保留默认值,这应该已经可以正常工作了:
[HttpGet("v1/users/{id}")]
public async Task<ActionResult> GetUser(string id)
{
return Ok(new { id = id });
}
[HttpGet("v1/users/me")]
public async Task<ActionResult> GetCurrentUser()
{
return Ok(new { id = "current" });
}
使用属性路由,包含 constant 部分的路由优于在同一位置包含路由变量的路由。因此 v1/users/me
的排名高于 v1/users/{id}
和 id = "me"
,因此当您访问该路由时,您应该看到 GetCurrentUser
运行。这与控制器中的方法顺序无关。
问题出在 API 端点方法的注释上。
我错误地将 GetUser(string id) 端点中的参数标记为 [FromQuery] 属性而不是 [FromRoute]。
以下按预期工作:
public class UsersController : ControllerBase
{
[HttpGet]
[Route("v1/users/{id}", Name = nameof(GetUser))]
public async Task<ActionResult> GetUser([FromRoute(Name = "id")] string userGuid)
{
// Changed from [FromQuery(Name = "id")] to [FromRoute(Name = "id")]
// Implementation omitted.
}
[HttpGet]
[Route("v1/users/me", Name = nameof(GetCurrentUser))]
public async Task<ActionResult> GetCurrentUser()
{
// Implementation omitted.
}
}