AspNetCore Route Token Replacement doesn't work with OData attribute routes
@xuzhg is already working on this.
Since Jan 12, 2022.
- Dominant language
- C#
- Stars
- 505
- Forks
- 186
- PR merge metrics
- No merged PRs in 30d
Description
- Latest affected version: Microsoft.AspNetCore.OData v8.0.5
When using attribute routes in OData v8, token replacement values are not handled properly, and the routes are treated as non-OData ones.
Let's use the standard controller created by the default web API project template with some slight modifications:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ODataController
{
[HttpGet]
public IEnumerable<WeatherForecast> Something()
{
...
}
}
The default template relies on the token replacement mechanism described here:
For convenience, attribute routes support token replacement by enclosing a token in square-brackets (
[,]). The tokens[action],[area], and[controller]are replaced with the values of the action name, area name, and controller name from the action where the route is defined
If we add OData to the project, and register WeatherForecast as an entityset in the EDM model, this route is still not picked up by OData and is treated as a non-OData route.

If we just replace the token with the actual value however, it is then treated as a proper OData route:
[ApiController]
[Route("WeatherForecast")]
public class WeatherForecastController : ODataController
{
[HttpGet]
public IEnumerable<WeatherForecast> Something()
{
...
}
}

I believe this is less than ideal for at least a couple of reasons:
- It is confusing/not orthogonal: consumers will be left wondering why OData is not working when converting normal controllers to OData. The use of token placeholders like
[controller]and[action]are extremely common - It leads to redundancy in code and refactor unfriendliness: changing the name of the entityset or controller won't affect the route as it should. Usually, there is a 1 to 1 match between the controller name, the actual entity being handled, and the route itself.
OData should support the same token replacement mechanism before deciding whether or not a given route is an OData route. What should matter is the final, substituted text route.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.