该请求与.NET Core上的多个端点匹配

时间:2020-10-05 13:51:14

标签: c# api rest .net-core webapi

我在.NET Core项目中使用OpenAPI(Swagger),并且在使用具有相似get请求的多种方法时,遇到“ Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:该请求与多个端点匹配”。运行时错误。我在Web和SO上浏览了多个页面,并尝试应用The request matched multiple endpoints but why?之类的变通办法,但是它不能解决问题。这是我使用的API方法和路由定义。

--WITH TOCOUNT AS (
    SELECT ROW_NUMBER() 
    over(
    PARTITION BY b.branchId
        ORDER BY LastCounted
    ) AS RowNo,
    b.BranchName AS [Branch], FullDesc, StockLevel, LastCounted, t.TargetCount AS [Target]
    FROM Product p
    JOIN Branch b
    ON p.Branch = b.ContractorCode
    JOIN TargetLineCount t
    ON b.BranchID = t.Branch
    WHERE LastCounted IS NOT NULL 
    AND StockLevel <> 0 
    AND t.ProductGroup = 'DISP'
)
INSERT INTO OutstandingCountStaging (RowNumber,Branch,Product,StockLevel, LastCounted, TargetCount)
SELECT * FROM TOCOUNT WHERE RowNo <= Target

我使用[Route("get", Name="get")] public IEnumerable<DemoDto> Get() { // } [Route("get/{id}", Name="getById")] public DemoDto GetById(int id) { // } [Route("get/{query}", Name="getWithPagination")] public IEnumerable<DemoDto> GetWithPagination(DemoQuery query) { // } 属性来解决问题但未解决。有什么想法要改变路由以区分NameGet()

3 个答案:

答案 0 :(得分:3)

[Route("get/{query}", Name="getWithPagination")]

这没有道理。 DemoQuery是一个对象,不能用网址的单个部分表示。不过,您可以告诉ModelBinder从多个查询参数构建对象。

路由引擎正在将此路由与[Route("get/{id}", Name="getById")]路由混淆。它们看起来都与get/blah匹配。

除了修正您的DemoQuery路线外,尝试在id路线上添加路线约束-

[Route("get/{id:int}", Name="getById")]

以更好地帮助引擎


要使DemoQuery正常工作,请假定它看起来像这样:

public class DemoQuery
{ 
     public string Name { get; set; }
     public int Value { get; set; }
}

然后将操作更改为

[Route("getPaged/{query}", Name="getWithPagination")]
public IEnumerable<DemoDto> GetWithPagination([FromQuery] DemoQuery query)

,然后调用端点/getPaged?name=test&value=123。然后ModelBinder应该为您构建对象。

答案 1 :(得分:2)

您有两个端点具有相等的路由: get / {id}和get / {query}。

如果您在浏览器行get / 123中编写,系统将无法理解要使用的路由,因为它们具有相同的模式。

您需要区分它们,我建议您对路线使用宁静的风格,例如: 项目/ {id}, 项目?{您的查询}

答案 2 :(得分:0)

ASP.NET Web API 2 支持一种新型路由。 Offical Doc

路由约束让您限制参数类型并匹配这些类型(整数、字符串、甚至日期等)。一般语法是“{parameter:constraint}”

[Route("users/{id:int}")]
public User GetUserById(int id) { ... }

[Route("users/{name}")]
public User GetUserByName(string name) { ... }

我在 API 上测试过;

//match : api/users/1 
[HttpGet("{id:int}")]
public IActionResult GetUserById(int id){ ... }

//match : api/users/gokhan
[HttpGet("{name}")]
public IActionResult GetUserByName(string name){ ... }