Проблема с маршрутизацией конечной точки в ASP. NET Web API (. NET Core 3.1) - PullRequest
2 голосов
/ 20 января 2020

Добрый день,

У меня возникли проблемы с маршрутизацией конечной точки в моем веб-API с использованием атрибутной маршрутизации и промежуточного программного обеспечения ASP. NET основной маршрутизации.

У меня есть Контроллер 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();
   }
}

Можно ли этого добиться с помощью атрибутной маршрутизации, и если да, то чего мне не хватает?

Спасибо!

Ответы [ 2 ]

1 голос
/ 20 января 2020

Это уже должно нормально работать, если вы просто оставите значения по умолчанию следующим образом:

[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 при доступе к этому маршруту. Это не зависит от порядка методов в вашем контроллере.

0 голосов
/ 21 января 2020

Проблема заключалась в аннотации методов конечной точки 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.
    }
}
...