Upgrading .Net Core 2.2 Web API with SWAGGER and ODATA to .Net COre 3.1

Decided to take the plunge and update a fairly sizeable WebAPI with OData and Swagger to .Net Core 3.1. Why the hell would you do this you may ask? Well to take advantage of 3.1’s endpoint routing and OData’s recent support for this with OData 7.40. Inspired by Hassan Habib’s blog entry on Microsoft Dev blogs and decided to go for it.

3 Plates Spinning

It’s been quite a challenge getting .Net Core, OData and Swagger to play nicely with each other over the last few months since I’ve been involved with the project so making the switch to 3.1 was not a casual afternoon’s work. That said I was pretty much there after a working day. In order to satisfy all 3 factors what follows is some of the key changes I took on and resolved in order to get all components working.


Ensuring that you have a solid working build and your ready to make the upgrade then it’s pretty straightforward. Simply target your projects to 3.1

Then you’ll need to upgrade your Nuget Packages in particular OData to 7.40 and Swashbuckle I went with 5.0.0. Ensure you’re getting a good build and then you’ll need to sort out the routing.


The .Net Core 2.2 Web API routing with OData and translating that into some kinda of meaningful Swagger OpenAPI out felt very sellotape and blu tack. For example, here’s the recommended approach….

as discussed over at https://github.com/rbeauchamp/Swashbuckle.OData/issues/154

Then if you want to use XML formatters you need to include those also. Which is pretty standard to be fair but as of 2.2 you’d need to take endpoint routing off and set the compatibility version to 2.2. What really changes in the upgrade are the Controllers. Whereas before without using endpoint routing you’ll decorate your routes with ODataRoute theses now simply become the standard api Route. Also bear in mind that if you’ve been using OData routes similar to [ODataRoute(“{id}/childcollection/{childId}”] then you’ll find that you’ll have to specify the id types otherwise they won’t be served. So in the example above this becomes [ODataRoute(“{id:int}/childcollection/{childId:int}”].

It works!

Simply put the upgrade was pretty straight forward and it worked. A quick rattle through Postman and all OData functionality was working as expected, Selects, Expands etc all fit and working.


As is the case throughout my blog any business context is removed.

Leave a Reply

%d bloggers like this: