在ASP.NET Core Web Api中具有多个带有多个查询字符串参数的get方法

本文关键字:字符串 查询 参数 方法 get ASP Api Web NET Core | 更新日期: 2023-09-27 18:00:09

我正在构建一个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。然而,在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

谢谢!

在ASP.NET Core Web Api中具有多个带有多个查询字符串参数的get方法

首先要混合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

但是您也指定了您期望xCoordinateyCoordinate从查询参数绑定。因此,上面的url将与操作匹配,但xCoordinateyCoordinate将绑定到它的默认值(在本例中为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&parameters=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
}

进一步阅读:

模型绑定/路由

快速提示:

appsettings.json中将Microsft loglevel设置为Debug(在标准Asp.Net Core WebApplication Template中自动生成),当在kestrel下运行时,您将在控制台输出中获得关于路由选择/错误的非常有用的信息。

{
  "Logging": {
  "IncludeScopes": false,
  "LogLevel": {
    "Default": "Debug",
    "System": "Information",
    "Microsoft": "Debug"
}

或者在StartUp.csLogLevel.Debug中设置调试记录器,您可以直接在Visual Studio中的调试输出中获得相同的信息。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // ...
        loggerFactory.AddDebug(LogLevel.Debug);
        // ...
    }