在 ASP.NET Core Web Api 中有多个带有多个查询字符串参数的 get 方法
Posted
技术标签:
【中文标题】在 ASP.NET Core Web Api 中有多个带有多个查询字符串参数的 get 方法【英文标题】:Having multiple get-methods with multiple query string parameters in ASP.NET Core Web Api 【发布时间】:2016-08-03 08:47:36 【问题描述】:我正在构建一个 web api,其中我有一个资源必须有 3 个 get 方法,如下所示:
[HttpGet]
[Route("city/streetName/streetNumber/littera")]
public IActionResult GetByAddress([FromQuery]string city, [FromQuery]string streetName, [FromQuery]int streetNumber, [FromQuery]string littera)
var model = _availabilityService.FindByAddress(city, streetName, streetNumber, littera);
return Ok(model);
[HttpGet("pointId")]
public IActionResult GetByPointId(string pointId)
var model = _availabilityService.FindByPointId(pointId);
return Ok(model);
[HttpGet]
[Route("xCoordinate/yCoordinate")]
public IActionResult GetByCoordinates([FromQuery]decimal xCoordinate, [FromQuery]decimal yCoordinate)
var model = _availabilityService.FindByCoordinates(xCoordinate, yCoordinate);
return Ok(model);
只有一个参数(pointId)的 get 方法工作正常,因为它不被视为查询字符串,而是 id。然而其余的 2 种方法似乎在 ASP.NET 中的路由器无法区分。
我真的很茫然,无法弄清楚为什么它不起作用。我能够解决的是,如果我删除其中一种方法,另一种方法可以正常工作。
关于我做错了什么有什么建议吗?
仅供参考,对应的 url:s 应该如下所示:
api/1.0/availabilities?city=Metropolis&streetName=Superstreet&streetNumber=1&littera=A
和
/api/1.0/availabilities?xCoordinate=34.3444&yCoordinate=66.3422
谢谢!
【问题讨论】:
当你说它不起作用时,你通过调用另外两个动作究竟得到了什么? 404? @jpgrassi:我刚刚收到 500 个内部服务器错误。我使用了调试器,发生的事情是甚至从未到达端点,所以我的结论是我的路由混乱和混乱。 :( 【参考方案1】:首先你要混合使用 RouteParameters 和 QueryParameters。
这个:
[HttpGet]
[Route("xCoordinate/yCoordinate")]
public IActionResult GetByCoordinates([FromQuery]decimal xCoordinate, [FromQuery]decimal yCoordinate)
var model = _availabilityService.FindByCoordinates(xCoordinate, yCoordinate);
return Ok(model);
将控制器操作GetByCoordinates
映射到这样的路由:
/api/1.0/availabilities/34.3444/66.3422
但您还指定您期望 xCoordinate
和 yCoordinate
与查询参数绑定。所以上面的 url 会匹配动作,但 xCoordinate
和 yCoordinate
会绑定到它的默认值(在本例中为 0)。
所以为了得到你想要的路由,你不应该声明路由参数:
[HttpGet]
[Route("")] // <- no route parameters specified
public IActionResult GetByCoordinates([FromQuery]decimal xCoordinate, [FromQuery]decimal yCoordinate)
// will be matched by e.g.
// /api/1.0/availabilities?xCoordinate=34.3444&yCoordinate=66.3422
现在您想要的路线将匹配。
注意:您不能将两个动作映射到同一个路由 - 路由中间件不知道该选择哪一个。因此,从GetByAddress
中删除路由参数也会有效地将两个操作映射到同一路由:
/api/1.0/availabilities?any=number&of=query¶meters=here
因此,例如,您将不得不通过另一个路线段来区分它们。
[HttpGet]
[Route("address")] // <--
public IActionResult GetByAddress([FromQuery]string city, [FromQuery]string streetName, [FromQuery]int streetNumber, [FromQuery]string littera)
// will be matched by e.g.
// api/1.0/availabilities/address?city=Metropolis&streetName=Superstreet&streetNumber=1&littera=A
进一步阅读:
ModelBinding/Routing
快速提示:
在appsettings.json
中将Microsft
日志级别设置为Debug
(在标准Asp.Net Core WebApplication 模板中自动生成),您将在运行时在控制台输出中获得有关路由选择/错误的非常有用的信息红隼。
"Logging":
"IncludeScopes": false,
"LogLevel":
"Default": "Debug",
"System": "Information",
"Microsoft": "Debug"
或者在StartUp.cs
到LogLevel.Debug
中设置调试记录器,您可以直接在Visual Studio 中的调试输出中获得相同的信息。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
// ...
loggerFactory.AddDebug(LogLevel.Debug);
// ...
【讨论】:
感谢您的精彩解释。您所描述的内容确实有道理。然而,这提出了一个新问题,它是否是一种传统的精简方式,为资源添加“路由词”以指定其含义?感谢您的回答,我已将其标记为已回答! :) @KasperP 在我看来,在设计 api 时做最适合你的事情。也就是说,特别是当您询问约定时,REST 将是您可以(尝试)遵循的约定/范式。我可能会在一个搜索操作中合并GetByAddress
和GetByCoordinates
,因为它似乎就是这样。 REST, URI-Design
感谢您的回答。对于诸如route/session?drop
之类的语法,是否有任何实用的方法来实现查询标志,其中参数 drop 指定如果有会话,则应删除会话。还是需要独特的路线?以上是关于在 ASP.NET Core Web Api 中有多个带有多个查询字符串参数的 get 方法的主要内容,如果未能解决你的问题,请参考以下文章
如何使 ASP.NET Core Web API 操作异步执行?
这是从 ASP.NET Core Web API 中的 EF Core 5 获得的啥样的响应 [关闭]
IdentityServer4 基于角色的 Web API 授权与 ASP.NET Core 身份