Comments (10)
Whoops! It should be:
options.ModelBuilder.ModelBuilderFactory = static () => new ODataConventionModelBuilder();
I've updated the comment. That's what happens when you try to do it all from memory. 😄
from aspnet-api-versioning.
Nice! Glad to see you moving to the new. The migration is a little rough, even with just plain 'ol OData, but the end result is largely better.
Issue 1
I don't have any control or influence over what the OData team does with routing. I just follow the leader. I can say that OData 8.0+ is more inline with intrinsic ASP.NET Core routing, which means you have less to learn about the OData way to do things. There's still gotchas and you have to know the OData URL conventions, but it's better. For API Versioning, this meant significantly less forking, hacking, and conversion of OData routing mechanics. I can lean in a lot more on what OData provides, especially for URL generation, which is nice.
Issue 2
When you say casing, I presume you are referring to the casing of JSON returned. I had to spelunk the commits, but this was changed over 5 years ago. Comparing dates, it looks like this has been the behavior for OData on ASP.NET Core since API Versioning 3.0.0-beta1
, which was the first version to support OData. If you had been using OData on legacy ASP.NET Web API, Pascal/Title case that was the default up until 2.2.0
. This change was made because the majority of users expect JSON to be Camelcase in alignment with JSON standards. Furthermore, that is the default in ASP.NET Core itself now (for years), even without OData. The goal was to have congruency and one less knob to turn.
Fear not! You can easily go back to Pascalcase if you want it.
var builder = WebApplication.CreateBuilder( args );
builder.Services.AddControllers().AddOData(); // ← this adds OData services
builder.Services.AddProblemDetails();
builder.Services.AddApiVersioning()
.AddOData( // ← this adds OData to API Versioning
options =>
{
// the default setup uses:
// new ODataConventionModelBuilder().EnableLowerCamelCase()
options.ModelBuilder.ModelBuilderFactory = static () => new ODataConventionModelBuilder();
// route components have to be add here (sadly 😢) because there is no way to extend,
// customize, or otherwise get in front of the OData configuration. every effort was made
// to make things look and feel like the native OData API and configuration
options.AddRouteComponents( "api" );
} );
Issue 3
The OData spec itself has continued to evolve. The $
prefix is no longer required. There's a long history that some implementers didn't like the $
prefix, which hindered adoption (like Azure). The original intend was for these query parameters to be unambiguously specific to OData. The OData spec now allows all System Operators to not require a $
prefix, which makes them look more like any other query parameter or REST API.
OData 8.0 established parity with this capability back in the first 8.0 release candidate circa 2/2021. The default configuration is to not include the $
, but you can add it back:
var builder = WebApplication.CreateBuilder( args );
// OData query options and route options are shared across all versioned routes so you only need
// to define them once for your application. Route components (e.g. AddRouteComponents) MUST
// be done through the API Versioning extensions not the native OData methods. such routes are
// ignored by API Versioning if you do.
//
// Re-enable the $ prefix
builder.Services.AddControllers().AddOData(options = options.EnableNoDollarQueryOptions = false);
builder.Services.AddProblemDetails();
builder.Services.AddApiVersioning().AddOData();
Issue 4
I'm not 100% sure on this one. Is this in reference to defining a parameter as optional in an EDM function or in the OpenAPI documentation? I'd have to refer back to the specs and documentation. OData has little-to-no OpenAPI support and it produces a lot less than the API Explorer extensions that API Versioning provides. My best guess is that there is either a mismatch or the route template isn't correct (which I've been snagged by many times).
I took a few of the existing functions and just added optional query parameters. It seemed to work just fine. I did not include the parameter in the EDM. I'm not sure if that is a requirement.
/// <summary>
/// Gets the sales tax for a postal code.
/// </summary>
/// <param name="postalCode">The postal code to get the sales tax for.</param>
/// <param name="extra">Something extra.</param>
/// <returns>The sales tax rate for the postal code.</returns>
[HttpGet( "api/GetSalesTaxRate(PostalCode={postalCode})" )]
[ProducesResponseType( typeof( double ), Status200OK )]
public IActionResult GetSalesTaxRate( int postalCode, string extra = null ) => Ok( 5.6 );
/// <summary>
/// Gets the new hires since the specified date.
/// </summary>
/// <param name="since">The date and time since people were hired.</param>
/// <param name="options">The current OData query options.</param>
/// <param name="extra">This is extra.</param>
/// <returns>The matching new hires.</returns>
/// <response code="200">The people were successfully retrieved.</response>
[HttpGet( "api/People/NewHires(Since={since})" )]
[Produces( "application/json" )]
[ProducesResponseType( typeof( ODataValue<IEnumerable<Person>> ), Status200OK )]
public IActionResult NewHires(
DateTime since,
ODataQueryOptions<Person> options,
string extra = null ) => Get( options );
from aspnet-api-versioning.
Thanks for the quick turn around. I believe it should be able to unblock our migration. I will reach out again for other issues/questions.
from aspnet-api-versioning.
Most of my issues are addressed except Issue 2 I get a compile time error.
'ODataApiVersioningOptions' does not contain a definition for 'ModelBuilderFactory' and no accessible extension method 'ModelBuilderFactory' accepting a first argument of type 'ODataApiVersioningOptions' could be found (are you missing a using directive or an assembly reference?)
from aspnet-api-versioning.
@commonsensesoftware been there done that :)
Thanks for your help!
from aspnet-api-versioning.
Hi, I'm currently using the version 7.6.3 and want to migrate to 8+. Can anyone help me with the what are the changes need to be done in startup.cs and controllers and modelbuilders with respect to odata 8+ with Asp.versioning.Odata and Asp.Versioning.Odata.ApiExplorer please. I'm stuck and confused about where to start.
from aspnet-api-versioning.
@Preethi-Angel Did you look at the examples?
from aspnet-api-versioning.
@cfauchere Yes I did, Thanks for sharing it. In the controllers, I get error on the lines where I have
return ok or notfound or badrequest. Anyone encountered the same?
from aspnet-api-versioning.
@Preethi-Angel Can you provide some more context or examples. If you have code or a repo you can share, that would be best.
In terms of differences, moving from OData 7.x to 8.x there are significant changes there, even without API Versioning. OData has a new configuration that looks like:
services.AddOData();
The normal OData configuration would define EDMs and routes here. Unfortunately, that will not work with API Versioning. I tried coordinating with the OData team, but nothing came of it. The only thing you can define there are common query and routing options (ex: $
or not, parenthesis key /Entities(42)
vs segment key /Entities/42
). These options copied to all versioned routes.
API Versioning now centralizes its configuration around IApiVersioningBuilder
. This makes all of the various extension points common and in one place. For example:
services.AddApiVersioning()
.AddOData(options => options.AddRouteComponents("api"))
.AddODataApiExplorer();
AddRouteComponents
does not require a prefix. AddRouteComponents
mirrors the built-in OData functionality in 8.x. ODataApiVersioningOptions.ModelBuilder
is how to now access the VersionedODataModelBuilder
. In earlier versions, you would have requested it directly though DI.
Aside from namespace changes, most other types, functionality, and behaviors are identical. There is no other change to IModelConfiguration
. It is still discovered and configured as it was before.
Happy to provide additional assistant or explanation, but without some more specifics, I'm not sure where to steer you.
from aspnet-api-versioning.
This issue has gone idle and the OP seems to have been answered. If it hasn't, I'm happy to re-open the issue and discuss further.
@Preethi-Angel , it's not clear if you ever resolved your issue. If you haven't, consider opening a discussion or open an new issue if you think you've hit a roadblock.
from aspnet-api-versioning.
Related Issues (20)
- OpenAPI not working with version interleaving within single controller HOT 3
- ActionDescriptor no longer returns an ApiVersionModel property HOT 2
- ApiVersioningOptions UseApiBehavior removal HOT 3
- ASP.NET Web API versioning Migrate from QueryStringApiVersionReader to UrlSegmentApiVersionReader HOT 2
- only the 5.1.0 version of Microsoft.AspNetCore.Mvc.Versioning is deprecated HOT 3
- Problem with describing reponse codes in minimal api HOT 3
- Cannot run APIs with different controller names with same ControllerName attribute after migration HOT 6
- Different options in `ApiVersioningOptions.cs` between .NET Framework and .NET Core packages HOT 2
- WithOpenApi() ignore Api versioning readers HOT 4
- .net 8 support HOT 7
- odata/$metadata returns 404 when all controllers are decorated with ApiVersionNeutralAttribute HOT 3
- AddVersionedApiExplorer not working in Asp.Versioning HOT 5
- VersionedApiDescriptionProvider does not set the correct SunsetPolicy to ApiDescription instances HOT 1
- Using ApiExplorerSettingsAttribute together with ApiVersionAttribute produces unexpected number of ApiVersionDescriptions HOT 5
- Asp.Net Core WebApi - AWS ECS Cluster Authentication failure HOT 2
- [Versioned Clients][API Notifications] Fails to read new versions when available HOT 2
- Swashbuckle documentation inconsistent with examples HOT 2
- AssumeDefaultVersionWhenUnspecified does not work correctly if ApiVersionNeutral is used in the controller HOT 2
- swagger.json file not found after update HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aspnet-api-versioning.