Core 2.1 APIVersioning Action двусмысленность - PullRequest
0 голосов
/ 13 января 2019

Я успешно настроил управление версиями API в своем проекте API Core 2.1.

http://localhost:8088/api/Camps/ATL2016/speakers?api-version=x.x

Версии 1.1 и 2.0 работают, но 1.0 дает сбой с неоднозначностью Get(string, bool) Actions.

Базовый веб-сервер ASP.NET:

MyCodeCamp> fail: Microsoft.AspNetCore.Mvc.Routing.DefaultApiVersionRoutePolicy[1] MyCodeCamp> Request matched multiple actions resulting in ambiguity. Matching actions: MyCodeCamp.Controllers.Speakers2Controller.Get(string, bool) (MyCodeCamp) MyCodeCamp> MyCodeCamp.Controllers.SpeakersController.Get(string, bool) (MyCodeCamp) MyCodeCamp> fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] MyCodeCamp> An unhandled exception has occurred while executing the request. MyCodeCamp> Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:

Контроллер Speakers2 украшен [ApiVersion("2.0")], поэтому действие Get(string, bool) имеет версию 2.0, так почему же Versioning не может отличить их друг от друга?

Microsoft.AspNetCore.Mvc.Versioning 3.0.0 (не удается установить более высокую версию из-за конфликтов версий)

Startup.cs:

  services.AddApiVersioning(cfg =>
    { cfg.DefaultApiVersion = new ApiVersion(1, 1);
      cfg.AssumeDefaultVersionWhenUnspecified = true;
      cfg.ReportApiVersions = true;     });

Контроллеры:

  [Route("api/camps/{moniker}/speakers")]
  [ValidateModel]
  [ApiVersion("1.0")]
  [ApiVersion("1.1")]
  public class SpeakersController : BaseController
  { 
    . . . 
    [HttpGet]
    [MapToApiVersion("1.0")]
    public IActionResult Get(string moniker, bool includeTalks = false)

    [HttpGet]
    [MapToApiVersion("1.1")]
    public virtual IActionResult GetWithCount(string moniker, bool includeTalks = false)

  [Route("api/camps/{moniker}/speakers")]
  [ApiVersion("2.0")]
  public class Speakers2Controller : SpeakersController
  {
    ...
    public override IActionResult GetWithCount(string moniker, bool includeTalks = false)

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Причина, по которой ваша предыдущая реализация не сработала, заключается в том, что [ApiVersion] и [MapToApiVersion] не унаследованы. Это может показаться нелогичным, но если бы это было так, то каждый подкласс продолжал бы накапливать версии API. Во 2-й реализации вы не переопределили исходный Get, поэтому он неявно стал 2.0, как указано контроллером. Вот почему вы видели дубликаты, потому что теперь это неоднозначно с GetWithCount.

0 голосов
/ 13 января 2019

Очевидно, что управление версиями путается с несколькими Getxxx IActionResult с.

Я заставил его работать, выполнив действие Get в Speakers controller virtual и затем overriding в Speakers2 controller как заполнитель, который не будет вызываться. Мне также пришлось применить [ApiVersion("2.0")] только к GetWithCount action, а не к controller.

[Authorize]
[Route("api/camps/{moniker}/speakers")]
[ValidateModel]
[ApiVersion("1.0")]
[ApiVersion("1.1")]
public class SpeakersController : BaseController

  [HttpGet]
  [MapToApiVersion("1.0")]
  [AllowAnonymous]
  public virtual IActionResult Get(string moniker, bool includeTalks = false)



[Route("api/camps/{moniker}/speakers")]
public class Speakers2Controller : SpeakersController

  public override IActionResult Get(string moniker, bool includeTalks = false)
  {  return NotFound(); }

  [ApiVersion("2.0")]
  public override IActionResult GetWithCount(string moniker, bool includeTalks = false)
...