0

Very possible this is a duplicate, but I've looked and can't find an answer. The first answer here looked promising: Query string not working while using attribute routing But I tried that and it didn't work.

[HttpGet, Route("api/machine/byid/{id=id}/{pageNumber=pageNumber}/{pageSize=pageSize}/{fields=fields}")]
public string ById(int id, int pageNumber, int pageSize, string fields)
    // code removed
}

This works:

https://localhost:44303/api/machine/byid/1/2/3/a,b,c

This does not:

https://localhost:44303/api/machine/byid?id=1&pageNumber=2&pageSize=3&fields=a,b,c

The second url returns:

{"type":"https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"|bf12950b-472923d3a24062d1.","errors":{"id":["The value 'id' is not valid."],"pageSize":["The value 'pageSize' is not valid."],"pageNumber":["The value 'pageNumber' is not valid."]}}

Community
  • 1
  • 1
Casey Crookston
  • 13,016
  • 24
  • 107
  • 193

3 Answers3

2

You would need two routes:

[HttpGet("api/machine/byid")]
public string ById(
    [FromQuery("id")] int id, 
    [FromQuery("pageNumber")] int pageNumber, 
    [FromQuery("pageSize")] int pageSize, 
    [FromQuery("fields")] string fields)
{
}

Follow this link for more informations

Jazzwave06
  • 1,883
  • 1
  • 11
  • 19
1

The example you provided demonstrates route parameters. There is a distinct difference between route parameters and query parameters.

To accomplish query parameters, you can the [FromQuery] attribute to your method parameters. This will allow for the query parameter example that you provided,

Example : https://localhost:5000/api/persons?firstName=bob&lastName=smith

You can also provide default values for these from within your method parameters. You can string multiple query parameters together in one action.

For route parameters, the parameters are provided via the route itself.

Example : https://localhost:5000/api/persons/23

These parameters are defined from within the [HttpGet("{id}")] attribute on your controller action. You can also constrain the parameter to a certain type, such as an int. This is achieved by adding a colon and specifying the type. Example [HttpGet("{id:int}")]. No further attributes are required to be added within your method parameters for route parameters.

Of course you must also declare these parameters in your method parameters, for both types.

// "/api/persons/23"
[HttpGet("{id}")]
public async Task<IActionResult> GetPersonById(int id)
{
    // Code ...
}

// "/api/persons?firstName=bob&lastName=smith"
[HttpGet]
public async Task<IActionResult> GetPersonByName([FromQuery] string firstName = null, [FromQuery] string lastName = null)
{
    // Code here... both firstName and lastName can now be optional or only one provided
}
jdewerth
  • 564
  • 3
  • 9
0

The answer by sturcotte06 was close, but was not 100% Core compliant. This works:

[HttpGet, Route("api/machine/byid/{id=id}/{pageNumber=pageNumber}/{pageSize=pageSize}/{fields=fields}")]
public string ById([FromQuery] int id, [FromQuery] int pageNumber, [FromQuery] int pageSize, [FromQuery] string fields)
{
    // code removed
}
Casey Crookston
  • 13,016
  • 24
  • 107
  • 193