Reputation: 1997
So I'm testing some of my routing out with Postman
and I can't seem to get this call to go through:
API Function
[RoutePrefix("api/Employees")]
public class CallsController : ApiController
{
[HttpGet]
[Route("{id:int?}/Calls/{callId:int?}")]
public async Task<ApiResponse<object>> GetCall(int? id = null, int? callId = null)
{
var testRetrieve = id;
var testRetrieve2 = callId;
throw new NotImplementedException();
}
}
Postman Requests
http://localhost:61941/api/Employees/Calls DOES NOT WORK
Error:
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:61941/api/Employees/Calls'.",
"MessageDetail": "No action was found on the controller 'Employees' that matches the request."
}
http://localhost:61941/api/Employees/1/Calls WORKS
http://localhost:61941/api/Employees/1/Calls/1 WORKS
Any idea why I can't use an optional between my prefix and the custom route? I've tried combining them into one custom route and that doesn't change anything, any time I try to cut out the id it causes problems.
Upvotes: 11
Views: 26232
Reputation: 247561
Optional parameters must be at the end of the route template. so what you are trying to do is not possible.
Attribute routing: Optional URI Parameters and Default Values
you either change your route template
[Route("Calls/{id:int?}/{callId:int?}")]
or create a new action
[RoutePrefix("api/Employees")]
public class CallsController : ApiController {
//GET api/Employees/1/Calls
//GET api/Employees/1/Calls/1
[HttpGet]
[Route("{id:int}/Calls/{callId:int?}")]
public async Task<ApiResponse<object>> GetCall(int id, int? callId = null) {
var testRetrieve = id;
var testRetrieve2 = callId;
throw new NotImplementedException();
}
//GET api/Employees/Calls
[HttpGet]
[Route("Calls")]
public async Task<ApiResponse<object>> GetAllCalls() {
throw new NotImplementedException();
}
}
Upvotes: 15
Reputation: 7352
Actually you dont need to specify optional parameter in route
[Route("Calls")]
or you need to change the route
[Route("Calls/{id:int?}/{callId:int?}")]
public async Task<ApiResponse<object>> GetCall(int? id = null, int? callId = null)
Upvotes: 1
Reputation: 59021
I would change the Route to:
[Route("Calls/{id:int?}/{callId:int?}")]
and add the [FromUri]
attribute to your parameters:
([FromUri]int? id = null, [FromUri]int? callId = null)
My test function looks like this:
[HttpGet]
[Route("Calls/{id:int?}/{callId:int?}")]
public async Task<IHttpActionResult> GetCall([FromUri]int? id = null, [FromUri]int? callId = null)
{
var test = string.Format("id: {0} callid: {1}", id, callId);
return Ok(test);
}
I can invoke it using:
https://localhost/WebApplication1/api/Employees/Calls
https://localhost/WebApplication1/api/Employees/Calls?id=3
https://localhost/WebApplication1/api/Employees/Calls?callid=2
https://localhost/WebApplication1/api/Employees/Calls?id=3&callid=2
Upvotes: 4