【问题标题】:Problem with endpoint routing in ASP.NET Web API (.NET Core 3.1)ASP.NET Web API (.NET Core 3.1) 中的端点路由问题
【发布时间】:2020-01-20 15:58:33
【问题描述】:

下午好,

我在使用属性路由和 ASP.NET 核心路由中间件的 Web 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”端点放在端点顺序中的另一个端点之前来解决这个问题,但路由中间件似乎不尊重 order 参数。在映射其余端点之前,我还尝试显式映射“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();
   }
}

这是否可以通过属性路由来实现,如果可以,我缺少什么?

谢谢!

【问题讨论】:

  • id 是 int 还是可以是任何字符串?
  • 需要一个字符串编码的 GUID,但它可以是任何字符串。

标签: c# asp.net-web-api-routing asp.net-core-3.1


【解决方案1】:

如果您只保留这样的默认值,这应该已经可以正常工作了:

[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 运行。这与控制器中的方法顺序无关。

【讨论】:

  • 感谢您的解释。我刚刚注意到我在原始代码中使用 [FromQuery] 而不是 [FromRoute] 注释了 {id} 参数。我猜这就是为什么我的原始代码没有按预期路由的原因。明天检查。
【解决方案2】:

问题在于 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.
    }
}

【讨论】:

    猜你喜欢
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多