Kas*_*r P 7 c# asp.net-core asp.net-core-routing
我正在构建一个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);
}
Run Code Online (Sandbox Code Playgroud)
只有一个参数(pointId)的get方法工作正常,因为它不被视为查询字符串,而是id和id.然而,似乎剩下的两种方法无法通过ASP.NET中的路由器区分.
我在这里真的很茫然,无法弄清楚它为什么不起作用.我能够解决的是,如果我删除其中一种方法,另一种方法可以正常工作.
关于我做错的任何建议?
仅供参考,相应的网址:应该如下所示:
api/1.0/availabilities?city=Metropolis&streetName=Superstreet&streetNumber=1&littera=A
Run Code Online (Sandbox Code Playgroud)
和
/api/1.0/availabilities?xCoordinate=34.3444&yCoordinate=66.3422
Run Code Online (Sandbox Code Playgroud)
谢谢!
小智 13
首先,您要混合RouteParameters和QueryParameters.
这个:
[HttpGet]
[Route("{xCoordinate}/{yCoordinate}")]
public IActionResult GetByCoordinates([FromQuery]decimal xCoordinate, [FromQuery]decimal yCoordinate)
{
var model = _availabilityService.FindByCoordinates(xCoordinate, yCoordinate);
return Ok(model);
}
Run Code Online (Sandbox Code Playgroud)
将控制器操作映射GetByCoordinates到这样的路由:
/api/1.0/availabilities/34.3444/66.3422
Run Code Online (Sandbox Code Playgroud)
但是您也指定了您期望xCoordinate并且yCoordinate与查询参数绑定.因此,上述网址将会匹配的动作,但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
}
Run Code Online (Sandbox Code Playgroud)
现在您想要的路线将匹配.
注意:您无法将两个操作映射到同一路由 - 路由中间件不知道选择哪个.因此,删除路由参数GetByAddress将有效地将两个动作映射到同一路径:
/api/1.0/availabilities?{any=number&of=query¶meters=here}
Run Code Online (Sandbox Code Playgroud)
因此,您必须通过其他路段来区分它们.
[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
}
Run Code Online (Sandbox Code Playgroud)
进一步阅读:
小建议:
将Microsftloglevel设置为Debugin appsettings.json(在标准的Asp.Net Core WebApplication Template中自动生成),当您在kestrel下运行时,在控制台输出中选择路由时,您将获得有关路由选择/错误的非常有用的信息.
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Debug"
}
Run Code Online (Sandbox Code Playgroud)
或者将调试记录器设置StartUp.cs为,LogLevel.Debug并在Visual Studio中直接在调试输出中获得相同的信息.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// ...
loggerFactory.AddDebug(LogLevel.Debug);
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13713 次 |
| 最近记录: |