-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
$orderby no longer working after upgrading from Microsoft.AspNetCore.OData 8.2.4 to 8.2.5 #1190
Comments
Does it change the error if you use |
Yes! It looks like my title should be "$orderby case sensitive after 8.2.5" |
Thanks for confirming, that was precisely my intent with the question 😉 There weren't many changes in the 8.2.5 release, so hopefully someone on the team will be able to quickly find which commit caused this regression. |
I think you need $skip and top in the odata query as well for it to fail |
Just did a bit of testing and it looks like you need a $top OR $skip value to induce this bug. My queries happen to get a default $top value if the request doesn't specify one, so I didn't catch that nuance. |
@jacobjohnston Can you share your failing request Uri with the query? |
@xuzhg For us an example query is https://localhost:4200/api/assistants?$orderby=displayName%20desc&top=15&$skip=0 Not sure what bit service configuration you want. we use also slight subtlety is and |
@justin-mellor Do you mind sharing your repro? attached the project here or share a github repository link? Thanks |
@xuzhg I will see if I can put one together |
Thanks. |
Hi @xuzhg I have attached a repro. There are examples in the .http file. If you reference 8.2.4 then all the cases pass. In 8.2.5 then the orderby with a top fails |
Hi @xuzhg . Decided to make it easier for everyone and push the repro to github |
Thanks for your reproduce, and it shows your "usage" clearly. Basically, if you follow up odata 'basic' usage as: 1Build the Edm model and use it build the odata endpoint: public static IEdmModel GetEdm()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Book>("Books");
builder.EntitySet<Press>("Presses");
return builder.GetEdmModel();
} builder.Services.AddControllers()
.AddOData(opt => opt.AddRouteComponents(..., GetEdm()); It works fine. 2If you continue to use the OData query only without the OData configuration. You can do the following as workaround: var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext<BookStoreContext>(opt => opt.UseInMemoryDatabase("BookLists"));
builder.Services.AddControllers()
.AddOData();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseODataRouteDebug();
app.Use(async (context, next) =>
{
context.Request.ODataFeature().Services = BuildProvider();
await next.Invoke();
});
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
static IServiceProvider BuildProvider()
{
var services = new ServiceCollection();
services.AddSingleton<ODataQuerySettings>();
services.AddSingleton<ODataUriParserSettings>();
services.AddSingleton(sp => new ODataUriResolver
{
EnableCaseInsensitive = true,
EnableNoDollarQueryOptions = true
});
services.AddSingleton<ODataSimplifiedOptions>();
return services.BuildServiceProvider();
} It works fine at my side for $orderby and $top. (It also works without the "$" prefix). Root causeThe root cause is that: In your usage, there's no OData property name case configuration, So, by default, OData library treats the property name case senstitive. I have a PR at #1192, please take a look and share your comments. |
Thanks for your response. Configuring the middleware does work for us, but I would rather wait for the default Case Insensitive change from your PR to be released. Realised the missing $ from $top was just a typo, hadn't even realised that was a feature. Hopefully this solves it for @jacobjohnston too. Thanks |
Hello @xuzhg , ❌ http://localhost:51994/project-statuses?$filter=((date+eq+2024-03-14))&$orderby=date+desc&$skip=0&$top=25 Second thing I do not understand is how presence of EDM model influcences this as in your example you did not specify case (in)sensitivity nor anything regarding name mapping. Does EDM model automatically make all properties camelCased? |
For your first thing. First, for ODataQueryOptions< T >, it enable case-insensitive by default if there's no OData service configured. So, you can see the codes at https://github.com/OData/AspNetCoreOData/blob/main/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs#L1156C17-L1163.All built-in Query options classes accept/use the same setting, because each query option takes the same "ODataQueryOptionParser". For example: https://github.com/OData/AspNetCoreOData/blob/main/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs#L983 So, $filter or other query options work fine except the $orderby. It's because if 'stable sorting enabled', we need to add the extra key into the orderby clause to make it stable sorting. For example, if the request query likes "?$orderby=date desc&$top=25", we need to add the "key" into the sorting. So the query should be changed (internally) as " ?$orderby=date desc,Id&$top=25". Then, we use 'https://github.com/OData/AspNetCoreOData/blob/main/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs#L765" to rebuild a OrderByQueryOption, then it creates a new ODataQueryOptionParser at 'https://github.com/OData/AspNetCoreOData/blob/main/src/Microsoft.AspNetCore.OData/Query/Query/OrderByQueryOption.cs#L104'. Since the new parser doesn't change the Uri resolver setting, then the Parser only supports the case sensitive by default. What I am thinking is that, why 'https://github.com/OData/AspNetCoreOData/blob/main/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs#L765' doesn't pass the existing ODataQueryOptionParser into the OrderByQueryOption constructor? For your second thing, Does EDM model automatically make all properties camelCased? ==> The answer is no. But, if you are using OData model builder and configured "EnableLowerCamelCase", the property and type name will be made as cameCased.Basically, OData model builder does two things for type and property. |
The workaround given above (adding ODataUriResolver to services) didn't work for me, and this bug is definitely still present in Microsoft.AspNetCore.OData 8.2.5 (latest available via Nuget)... |
Why is this closed? This is still broken in the latest 8.2.* version. This is a breaking change from 8.2.4 and needs to be fixed... |
Assemblies affected
Microsoft.AspNetCore.OData 8.2.5
Describe the bug
Using $orderby on a field returns an error saying the field does not exist. However, if I do a query where I just use a $filter on the field, it works entirely fine.
This started with 8.2.5. Rolling back to 8.2.4 and everything works fine again.
Reproduce steps
Add $orderby to my query, and I get the following error:
Data Model
The text was updated successfully, but these errors were encountered: