v8-9: Api controllers using default 'id' parameter
Closed this issue · 0 comments
Oooh this was a "fun" one to solve!
In the v8 site we have an UmbracoApiController
that returns various content for the front-end scheduler tool for our events.
v8
public class ScheduleApiController : UmbracoApiController
{
public IEnumerable<CheckBoxViewModel> GetDays(int id)
{
...
}
public IEnumerable<CheckBoxViewModel> GetActivities(int id)
{
...
}
}
Calls to this controller were being made with urls such as /umbraco/api/ScheduleApi/GetDays/1234.
v9
The above code compiled in v9, but the methods weren't getting the correct id
parameter from the url. It appears that UmbracoApiController wasn't model binding properly for the id route parameter. We tried various things, including:
GetDays([FromQuery(Name="id")]int id)
- nope!GetDays([FromBody]int id)
- still no!- We could add
[Route("umbraco/api/ScheduleApi/GetDays/{id}")]
to the method but surely a better way! - Slightly better was adding
[Route("umbraco/api/ScheduleApi")]
to the controller and then only[HttpGet("GetDays/{id:int}")]
to the method, but still not great - Finally we landed upon
[FromRoute]int id
, no route attributes required!
The resulting code looks like this:
public class ScheduleApiController : UmbracoApiController
{
private readonly UmbracoHelper _umbracoHelper;
public ScheduleApiController(UmbracoHelper umbracoHelper)
{
_umbracoHelper = umbracoHelper;
}
public IEnumerable<CheckBoxViewModel> GetDays([FromRoute]int id)
{
...
}
public IEnumerable<CheckBoxViewModel> GetActivities([FromRoute] int id)
{
...
}
}
Paul from Umbraco HQ had joined us at this point (and helped us land upon our final solution). He also acknowledged that this looked like a bug so raised an issue, and subsequent pull request to fix it.