我在.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)
{
//
}
属性来解决问题但未解决。有什么想法要改变路由以区分Name
和Get()
?
答案 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){ ... }