该请求与 .NET Core 上的多个端点匹配
The request matched multiple endpoints on .NET Core
我在 .NET Core 项目中使用 OpenAPI (Swagger),当使用具有类似 get 请求的多个方法时,我遇到“Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:请求匹配多个端点。”运行时出错。我查看了 Web 和 SO 上的几个页面,并尝试应用 等变通方法,但它并没有解决问题。这是我使用的 API 方法和路由定义。
[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()
和 GetWithPagination()
?
您有两个端点具有相同的路由:
get/{id} 和 get/{query}.
如果您在浏览器行中写入:get/123,系统无法理解要使用的路由,因为它们具有相同的模式。
你需要区分它们,我建议你使用 restful 路由样式,例如:
项目/{id},
项目?{您的查询}
[Route("get/{query}", Name="getWithPagination")]
这没有意义。 DemoQuery
是一个对象,不能用url的单个部分来表示。不过,您可以告诉 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 应该为您构建对象。
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){ ... }
我在 .NET Core 项目中使用 OpenAPI (Swagger),当使用具有类似 get 请求的多个方法时,我遇到“Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:请求匹配多个端点。”运行时出错。我查看了 Web 和 SO 上的几个页面,并尝试应用
[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()
和 GetWithPagination()
?
您有两个端点具有相同的路由: get/{id} 和 get/{query}.
如果您在浏览器行中写入:get/123,系统无法理解要使用的路由,因为它们具有相同的模式。
你需要区分它们,我建议你使用 restful 路由样式,例如: 项目/{id}, 项目?{您的查询}
[Route("get/{query}", Name="getWithPagination")]
这没有意义。 DemoQuery
是一个对象,不能用url的单个部分来表示。不过,您可以告诉 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 应该为您构建对象。
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){ ... }