api - Asp.Versioning.Http 模糊匹配异常 : The request matched multiple endpoints on controllers

标签 api controller asp.net-web-api-routing api-versioning aspnet-api-versioning

我正在尝试使用 Asp.Versioning.Http 包版本 6.4.0 在我的 Controller 上实现基于 header 的版本控制 它应该非常简单here但是我得到AmbigeousMatchException:请求匹配多个端点异常

这是我的程序类

我的 Controller 定义如下:

    var builder = WebApplication.CreateBuilder(args);
    // Add services to the container.
    builder.Services.AddControllers();

    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddApiVersioning(options => {
       // options.ApiVersionReader = new HeaderApiVersionReader("api-version");
        options.DefaultApiVersion = new ApiVersion(1.0);
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.ReportApiVersions = true;
    }).EnableApiVersionBinding();
    builder.Services.AddMvc();
    builder.Services.AddSwaggerGen();

    var app = builder.Build();

    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
       // app.UseSwagger();
        //app.UseSwaggerUI();
    }

    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    app.MapHealthChecks("/health/live");
    app.MapControllers();
    app.Run();
   namespace Things.Service.Controllers.V1
   {
    [ApiController]
    [ApiConventionType(typeof(DefaultApiConventions))]
    [Route("[controller]")]
    [Asp.Versioning.ApiVersion(1.0)]
    public class ThingsController : ControllerBase
    {
       // controller logic
    }
   }
    namespace Things.Service.Controllers.V2
    {
    [ApiController]
    [ApiConventionType(typeof(DefaultApiConventions))]
    [Route("[controller]")]
    [Asp.Versioning.ApiVersion(2.0)]`your text`
    public class ThingsController : ControllerBase
     {
       // controller logic
     }
    }

我得到这个异常:

    Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple    endpoints. Matches: 

Things.Service.Controllers.V2.ThingsController.GetAllAsync (Things.Service)
Things.Service.Controllers.V1.ThingsController.GetAllAsync (Things.Service)

最佳答案

发生这种情况是因为您缺少AddMvc。不要让这个名字欺骗了您,这添加了 MVC Core,而不是完整的 MVC 堆栈。从 6.0 开始,新设置以 IApiVersioningBuilder 为中心,以便所有设置都集中在一个位置,并且希望更易于遵循。如果您使用的是早期版本(例如 <= 5.x),这可能会让人感到惊讶。此更改是必要的,因为 AddApiVersioning 现在是 Minimal API 的基础,其中不包括 MVC Core 或 Controller 支持。 AddMvc 添加了这些功能。

         
services
 .AddApiVersioning()     // Asp.Versioning.Http : Core services and Minimal APIs
 .AddMvc()               // Asp.Versioning.Mvc : MVC Core
 .AddApiExplorer()       // Asp.Versioning.Mvc.ApiExplorer : API Explorer
 .AddOData()             // Asp.Versioning.OData : OData support
 .AddODataApiExplorer(); // Asp.Versioning.OData.ApiExplorer : OData API Explorer

由于您使用的是 MVC Core 和 Controller ,因此不需要 EnableApiVersionBinding。 MVC Core 支持模型绑定(bind)器。 AddMvc 将注册所有这些服务。如果您想在 Controller 操作中接收传入的 ApiVersion,您只需添加一个 ApiVersion 类型的参数以及您选择的名称。例如:

namespace Things.Service.Controllers.V1
{
   [ApiVersion(1.0)]
   [ApiController]
   [ApiConventionType(typeof(DefaultApiConventions))]
   [Route("[controller]")]
   public class ThingsController : ControllerBase
   {
      [HttpGet]
      public IActionResult Get(ApiVersion version) => Ok();
   }
}

最小 API 没有办法支持这种类型的模型绑定(bind)。 EnableApiVersionBinding 提供了一种使其工作的方法。添加它不会有什么坏处,但没有必要。

最后,您似乎已在命名空间中包含了版本号。如果这确实是您的设置,您可以考虑使用 VersionByNamespaceConvention。这将不需要用 [ApiVersion] 装饰 Controller 。 API 版本将从命名空间本身派生。有关更多详细信息,请参阅Version By Namespace Convention文档。

关于api - Asp.Versioning.Http 模糊匹配异常 : The request matched multiple endpoints on controllers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75248836/

相关文章:

javascript - 切换按钮以显示/隐藏来自 API 的数据

c# - Web API 2 路由属性不起作用

c# - 如何在一个 Controller 中调用三个get方法?

web-services - 在 laravel/lumen 中使用客户端 ID 和 key 访问 API

ruby - 使用 Bundler 解析 Gemfile.lock

asp.net - 插入_ViewStart.cshtml

ruby-on-rails - 在 ruby​​ on rails 中选择复选框传递数组

javascript - 前端 Web API 资源使用情况

node.js - NodeJS-设置传出HTTP请求的端口

spring - 多个 Spring Controller 的最佳实践。我应该遵循基于功能还是基于用户?