简体   繁体   English

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

[英]Having multiple get-methods with multiple query string parameters in ASP.NET Core Web Api

I'm building a web api where I have one resourse that must have 3 get methods as follows: 我正在构建一个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);
    }

The get method with only one parameter(pointId) is working fine since it is not seen as a query string but rather and id. 只有一个参数(pointId)的get方法工作正常,因为它不被视为查询字符串而是id和id。 However the remaining 2 methods are not distinguishable by the router in ASP.NET, it seems. 然而,似乎剩下的两种方法无法通过ASP.NET中的路由器区分。

I'm really at a loss here and cannot figure out why it doesn't work. 我在这里真的很茫然,无法弄清楚它为什么不起作用。 What I have been able to work out is that if I remove one of the methods the other one works fine. 我能够解决的是,如果我删除其中一种方法,另一种方法可以正常工作。

Any suggestions on what I'm doing wrong? 关于我做错的任何建议?

FYI, the corresponding url:s ought to look like the following: 仅供参考,相应的网址:应该如下所示:

api/1.0/availabilities?city=Metropolis&streetName=Superstreet&streetNumber=1&littera=A

and

/api/1.0/availabilities?xCoordinate=34.3444&yCoordinate=66.3422

Thanks! 谢谢!

First of all you are mixing RouteParameters and QueryParameters. 首先,您要混合RouteParameters和QueryParameters。

This: 这个:

[HttpGet]
[Route("{xCoordinate}/{yCoordinate}")]
public IActionResult GetByCoordinates([FromQuery]decimal xCoordinate, [FromQuery]decimal yCoordinate)
{
    var model = _availabilityService.FindByCoordinates(xCoordinate, yCoordinate);
    return Ok(model);
}

maps the controller action GetByCoordinates to a route like this: 将控制器操作GetByCoordinates映射到这样的路由:

/api/1.0/availabilities/34.3444/66.3422

But you are also specifying that you are expecting xCoordinate and yCoordinate to be bound from query parameters. 但是您还指定您希望xCoordinateyCoordinate与查询参数绑定。 So above url would match the action, but xCoordinate and yCoordinate would be bound to it's default values (in this case 0). 所以上面的url会匹配动作,但是xCoordinateyCoordinate会绑定到它的默认值(在本例中为0)。

So to get your desired route, you shouldn't declare route parameters: 因此,要获得所需的路线,您不应声明路线参数:

[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
}

Now your desired route will match. 现在您想要的路线将匹配。

Note: You cannot map two actions to the same route - the route middleware wouldn't know which one to select. 注意:您无法将两个操作映射到同一路由 - 路由中间件不知道选择哪个。 So also removing the route parameters from GetByAddress will effectively map both actions to the same route: 因此,从GetByAddress删除路由参数将有效地将两个操作映射到同一路由:

/api/1.0/availabilities?{any=number&of=query&parameters=here}

So you will have to differentiate them by another route segment for example. 因此,您必须通过其他路段来区分它们。

[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
}

Further reading: 进一步阅读:

ModelBinding / Routing 模型绑定 / 路由

Quick tip: 小建议:

Set Microsft loglevel to Debug in appsettings.json (auto generated in standard Asp.Net Core WebApplication Template) and you will get very useful information on route selection / errors while route selection in your console output when running under kestrel. 设置Microsft记录等级来Debugappsettings.json (自动标准Asp.Net核心WebApplication的模板生成的),你将获得的路由选择是非常有用的信息/错误,同时在红隼运行时在控制台输出路径选择。

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

Or set up the debug logger in StartUp.cs to LogLevel.Debug and you get the same information in debug output directly in Visual Studio. 或者将StartUp.cs的调试记录器StartUp.csLogLevel.Debug并在Visual Studio中直接在调试输出中获得相同的信息。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // ...

        loggerFactory.AddDebug(LogLevel.Debug);

        // ...
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM