Having multiple get methods with multiple query string parameters in ASP.NET Core Web Api

I am creating a web api where I have one resource that should have 3 methods:

[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) works fine, because it is not considered as a query string, but rather an id. However, apparently, the other 2 methods are not recognized by the router in ASP.NET.

I am really in difficulty and cannot understand why this is not working. What I was able to work out is that if I delete one of the methods, the other will work fine.

Any suggestions on what I'm doing wrong?

FYI corresponding url: s should look like this:

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

and

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

Thanks!

+5
source share
1 answer

First of all, you mix RouteParameters and QueryParameters.

It:

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

maps the action of the GetByCoordinates controller to the route as follows:

 /api/1.0/availabilities/34.3444/66.3422 

But you also indicate that you expect xCoordinate and yCoordinate be associated with the request parameters. Thus, the above url will match the action, but xCoordinate and yCoordinate will be bound to its default values ​​(in this case, 0).

So, in order to get the desired route, you should not specify route parameters:

 [HttpGet] [Route("")] // <- no route parameters specified public IActionResult GetByCoordinates([FromQuery]decimal xCoordinate, [FromQuery]decimal yCoordinate) { // will be matched by eg // /api/1.0/availabilities?xCoordinate=34.3444&yCoordinate=66.3422 } 

Now your desired route will match.

Note. . You cannot compare two actions with the same route - the route middleware will not know which one to choose. Thus, removing route parameters from GetByAddress will effectively map both actions to the same route:

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

Thus, you will have to differentiate them by another segment of the route, for example.

 [HttpGet] [Route("address")] // <-- public IActionResult GetByAddress([FromQuery]string city, [FromQuery]string streetName, [FromQuery]int streetNumber, [FromQuery]string littera) { // will be matched by eg // api/1.0/availabilities/address?city=Metropolis&streetName=Superstreet&streetNumber=1&littera=A } 

Further reading:

ModelBinding / Routing

Quick tip:

Install Microsft loglevel on Debug in appsettings.json (automatically generated in the standard WebApplication Asp.Net template), and you will get very useful information about route selection / errors when choosing a route on your console output when working under kestrel.

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

Or configure the debug log in StartUp.cs on LogLevel.Debug , and you will get the same information in the debug output directly in Visual Studio.

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

All Articles