在 ASP.NET Core 中使用 url 进行版本控制 - 多个匹配端点的问题

Versioning with url in ASP.NET Core - problem with multiple matching endpoints

提问人:Filip Tobiasz 提问时间:11/18/2023 更新时间:11/18/2023 访问量:22

问:

我正在制作我的 API 的 v2。在 v1 中,我在 URL 中有版本,所以它是 api/v1/something。现在我正在添加 API 的第二个版本,并决定使用 Asp.Versioning.Mvc。所以目前我的控制器看起来像这样:

[Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    [ApiVersion("1.0")]
    [ApiVersion("2.0")]
    public class SomeController : ControllerBase
    {
        //ctor

        [HttpGet]
        [MapToApiVersion("1.0")]
        public async Task<ActionResult<SomeResponse?>> GetSomethingV1([FromQuery] string text)
        {
            ...
        {

        [HttpGet]
        [MapToApiVersion("2.0")]
        public async Task<ActionResult<SomeResponse?>> GetSomethingV2([FromQuery] string text)
        {
            ...
        {
    }

在 Startup.cs 中也是如此

services.AddApiVersioning(config =>
            {
                config.DefaultApiVersion = new ApiVersion(2.0);
                config.AssumeDefaultVersionWhenUnspecified = true;
                config.ReportApiVersions = true;
            });
services.AddMvc();

不幸的是,它一直给我异常 Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:请求匹配多个终结点。知道为什么会这样吗?

我尝试了几种属性组合来测试我是否理解了错误,但它没有奏效。

C# asp.net 版本控制

评论

0赞 Heretic Monkey 11/18/2023
提供详细信息。什么请求引发了该异常?
0赞 Filip Tobiasz 11/18/2023
好吧,既然只有 Get 控制器,假设它是 api/v1.0/Some?text=test 上的 GET。api/v2.0/Some?text=test 也是如此

答:

0赞 Rush 11/18/2023 #1

我建议您将版本拆分为单独的控制器。在同一个控制器中拥有两个不同的版本是令人困惑 ASP.NET。1.02.0

喜欢这个

[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
[ApiVersion("1.0")]
public class SomeController : ControllerBase
{
    //ctor

    [HttpGet]
    [MapToApiVersion("1.0")]
    public async Task<ActionResult<SomeResponse?>> GetSomethingV1([FromQuery] string text)
    {

    }

}

[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
[ApiVersion("2.0")]
public class SomeController : ControllerBase
{
    //ctor

    [HttpGet]
    [MapToApiVersion("2.0")]
    public async Task<ActionResult<SomeResponse?>> GetSomethingV2([FromQuery] string text)
    {

    }
}

这样,您可以组织版本,它们各自的控制器。如果您不想为单个域创建两个版本,也可以使用继承。但这会变得棘手,正如这里提到的: https://github.com/dotnet/aspnet-api-versioning/issues/801#issuecomment-1025948364

评论

0赞 Filip Tobiasz 11/18/2023
所以不可能将它们放在同一个控制器中吗?我以为是,但在文档中找不到任何关于它的信息
0赞 Rush 11/19/2023
我认为这是不可能的