Write a simple function which returns in memory fixed data
Call that function concurrently with different $fitlers
You'd expect results filtered based on the provided filter
But you'll see invalid responses
OData 7.5.4+ has this issue (including 8 prev3)
OData 7.5.2 and lower versions are fine
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOData();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.Select().Filter().OrderBy().Count().Expand().MaxTop(100);
endpoints.MapODataRoute("odata", "odata", GetEdmModel());
});
}
IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new();
builder.EntitySet<TestModel>("Test");
return builder.GetEdmModel();
}
}
public class TestModel
{
public int Id { get; set; }
}
public class TestController : ODataController
{
[HttpGet, EnableQuery, ODataRoute("Test")]
public IQueryable<TestModel> Test()
{
return Enumerable.Range(1, 100)
.Select(i => new TestModel
{
Id = i
}).AsQueryable();
}
}
[TestClass]
public class Test
{
[TestMethod]
public async Task Impl()
{
IHostBuilder hostBuilder = new HostBuilder()
.ConfigureWebHost(webHost =>
{
webHost.UseTestServer();
webHost.UseStartup<Startup>();
});
using IHost host = await hostBuilder.StartAsync();
using HttpClient client = host.GetTestClient();
var results = await Task.WhenAll(Enumerable.Range(1, 100).Select(i => client.GetCount(i)));
foreach (var result in results)
{
Assert.AreEqual(100 - result.i, result.length);
}
}
}
public static class HttpClientExtensions
{
public static async Task<(int i, int length)> GetCount(this HttpClient client, int i)
{
return (i, (await (await client.GetAsync($"odata/test?$filter=Id gt {i}")).EnsureSuccessStatusCode().Content.ReadFromJsonAsync<JsonElement>()).GetProperty("value").GetArrayLength());
}
}
The test should get passed all the time
It gets passed on OData 7.5.2 and lower versions, but it fails on OData 7.5.4+
ODataConcurrentRequestsIssue.zip
Any time you switch between 7.5.4 and 7.5.2, perform clean/rebuild
The user is asking for data in the following scenario:
Hey OData, please show me invoices of data on 01/05/2021, and OData is showing her data for 04/05/2020!
Why? Because another user is asking that period at the same time.
That broken nuget package (Version 7.5.4 should get unlist ASAP)
@xuzhg
@ysmoradi Thanks for reaching me.
I tested it. When I run request individually as:

And I changed the "Test()" method to return `IQueryable < TestModel >" as:

This change will hit the OData formatter and output the OData payload. Otherwise, it will go to the default ASP.NET Core Json formatter.
By the way, Is it related to the "Concurrent request"?
This has to be an effect of the same issue as https://github.com/OData/WebApi/issues/2390
The QueryOptions are no longer thread safe since PR #2362
Fix has been made to both v7 and v8 repos.
Thanks @RamjotSingh
Most helpful comment
Fix has been made to both v7 and v8 repos.