How do you use versioning with OData attribute routing? #961
-
I'm trying to use api versioning with odata attribute routing, but can't seem to find any way in which it works. I'm using Asp.Versioning.OData 6.4.0, but had the same issues in version 7 too. I set up my services the way I would expect for versioning in the url segment: var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddControllers()
.AddOData();
builder.Services
.AddApiVersioning(options => options.ApiVersionReader = new UrlSegmentApiVersionReader())
.AddOData(options =>
{
options.ModelBuilder.DefaultModelConfiguration = (builder, apiVersion, routePrefix) =>
{
builder.EntitySet<Person>("People");
};
options.AddRouteComponents("api/v{version:apiVersion}");
}); Then I setup a controller as follows (note I'm specifically avoiding convention based action names to enforce that it uses the attribute routing only): [ApiVersion(1)]
[ApiVersion(2)]
[Route("api/v{version:apiVersion}")]
public class PeopleController : ODataController
{
[HttpGet("people")]
public IActionResult GetAll()
{
return Ok(new List<Person>());
}
[HttpPost("people")]
public IActionResult PostAPerson()
{
return Ok();
}
} I get the following error:
If I remove the I have similar issue using the The only way I can get anything to work is to use convention based routing, is attribute routing not supported, or am I missing something? I can push a simple git repo with my code if that would help. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Honestly, this is probably a question better suited for the OData team, but I'll do my best to answer anyway. API Versioning doesn't change the way that attribute routing works in OData. The mapping is a bit strange to me and the documentation that shows E2E configuration is lacking IMHO. It certainly doesn't appear to work the way one might expect. If you find that it works normally, but then stops working when you apply API Versioning, then there might be an issue. It took a lot of tinkering, but this configuration did finally work: [ApiVersion( 1 )]
[ApiVersion( 2 )]
public class PeopleController : ODataController
{
[HttpGet( "api/v{version:apiVersion}/people" )]
[HttpGet( "api/v{version:apiVersion}/people/$count" )]
public IActionResult GetAll()
{
return Ok( new List<Person>() );
}
[HttpPost( "api/v{version:apiVersion}/people" )]
public IActionResult PostAPerson( [FromBody] Person person )
{
return Ok();
}
} As far as I can tell, the OData routing infrastructure does not honor built-in route tokens such as Ultimately, going the path of route attributes feels tried and true, but you still have to know the OData routing conventions and match it if you want the full OData feature set. Even when some parts work, you might be missing other parts that you didn't realize you're missing; for example, The OData route debugging middleware is extremely useful in figuring out if you did things right: if ( app.Environment.IsDevelopment() )
{
// navigate to ~/$odata to determine whether any endpoints did not match an odata route template
app.UseODataRouteDebug();
} If you have an expected OData route and it doesn't show up in the OData list, then you know something is configured incorrectly. I hope that helps. |
Beta Was this translation helpful? Give feedback.
Honestly, this is probably a question better suited for the OData team, but I'll do my best to answer anyway. API Versioning doesn't change the way that attribute routing works in OData. The mapping is a bit strange to me and the documentation that shows E2E configuration is lacking IMHO. It certainly doesn't appear to work the way one might expect. If you find that it works normally, but then stops working when you apply API Versioning, then there might be an issue.
It took a lot of tinkering, but this configuration did finally work: