首页 > 解决方案 > Core 2.1 APIVersioning 动作歧义

问题描述

我已经在我的 Core 2.1 API 项目中成功设置了 API 版本控制。

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

版本1.12.0工作,但因操作1.0不明确而失败Get(string, bool)

ASP.NET Core Web 服务器:

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(由于版本冲突,无法安装更高版本)

启动.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)

标签: c#asp.net-web-apiasp.net-coreapi-versioning

解决方案


Getxxx IActionResult显然版本控制与多个s混淆了。

我通过在 the 中进行Get操作,Speakers controller virtual然后overriding将其Speakers2 controller作为不会被调用的占位符来使其工作。我还必须将[ApiVersion("2.0")]only 应用于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)

推荐阅读