AspNetCoreOData icon indicating copy to clipboard operation
AspNetCoreOData copied to clipboard

Regression in $apply=compute with Microsoft.AspNetCore.OData versions >= 8.0.5: "The given model does not contain the type" error

Open kardelw1409 opened this issue 9 months ago • 3 comments

Assemblies affected

The issue occurs in Microsoft.AspNetCore.OData versions starting from 8.0.5 and up to 9.2.0. The last known working version is 8.0.4.


Describe the bug

A regression occurs when using $apply=compute in OData queries. The query that worked in Microsoft.AspNetCore.OData version 8.0.4 now fails in versions 8.0.5 and later. The error indicates that the model does not contain the type Microsoft.AspNetCore.OData.Query.Wrapper.ComputeWrapper.

This issue is critical because our clients actively rely on $apply=compute queries in production environments, and the inability to use this functionality disrupts their workflows.


Reproduce steps

  1. Create a new ASP.NET Core Web API project with OData setup.
  2. Add the Microsoft.AspNetCore.OData NuGet package version 8.0.4.
  3. Define a simple entity model, for example:
public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}
  1. Configure OData in Program.cs:
using Microsoft.AspNetCore.OData;
using Microsoft.OData.ModelBuilder;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddOData(opt =>
    {
        var odataBuilder = new ODataConventionModelBuilder();
        odataBuilder.EntitySet<MyEntity>("MyEntities");
        opt.AddRouteComponents("odata", odataBuilder.GetEdmModel());
        opt.EnableQueryFeatures();
    });

var app = builder.Build();

app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
  1. Create a sample controller:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;

[Route("odata/[controller]")]
public class MyEntitiesController : ODataController
{
    private static List<MyEntity> _entities = new List<MyEntity>
    {
        new MyEntity { Id = 1, Name = "Entity1" },
        new MyEntity { Id = 2, Name = "Entity2" }
    };

    [EnableQuery]
    public IActionResult Get()
    {
        return Ok(_entities);
    }
}
  1. Run the application and make the following OData query:
GET http://localhost:5260/odata/MyEntities?$apply=compute(substring(Name, 1, 4) as comp)&$top=1&$count=true
  1. Observe the response:
    • With Microsoft.AspNetCore.OData version 8.0.4:
      {
          "@odata.context": "http://localhost:5260/odata/$metadata#MyEntities",
          "@odata.count": 2,
          "value": [
              {
                  "@odata.id": null,
                  "comp": "ntit",
                  "Id": 1,
                  "Name": "Entity1"
              }
          ]
      }
      
    • With Microsoft.AspNetCore.OData version 8.0.5 or later (9.2.0):
      {
          "error": {
              "code": "",
              "message": "The query specified in the URI is not valid. The given model does not contain the type 'Microsoft.AspNetCore.OData.Query.Wrapper.ComputeWrapper`1[[MyEntity, MyODataProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'.",
              "details": [],
              "innererror": {
                  "message": "The given model does not contain the type 'Microsoft.AspNetCore.OData.Query.Wrapper.ComputeWrapper`1[[MyEntity, MyODataProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'.",
                  "type": "Microsoft.OData.ODataException",
                  "stacktrace": "   at Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext..ctor(IEdmModel model, ODataQuerySettings querySettings, Type clrType)\r\n   at ..."
              }
          }
      }
      

Expected behavior

The query $apply=compute should work as expected, similar to how it works in version 8.0.4. The response should include the computed field (comp) based on the substring function.


Additional context

  • The issue appears to be related to how ComputeWrapper is handled in the OData library starting from version 8.0.5.
  • Rolling back to version 8.0.4 resolves the issue.
  • This issue is critical because our clients actively rely on $apply=compute queries in production environments. Fixing this regression is essential to ensure their workflows are not disrupted.

kardelw1409 avatar Feb 13 '25 11:02 kardelw1409

Hi @kardelw1409 what is the output that you get when you use $compute directly vs using $apply with $compute https://devblogs.microsoft.com/odata/compute-and-search-in-asp-net-core-odata-8/

marabooy avatar Feb 18 '25 16:02 marabooy

Hi @marabooy, yes, the query with $compute directly works. However, we have many clients relying on the $apply=compute format in their workflows. Compatibility with the old query format is crucial for us to avoid disruptions in production environments.

kardelw1409 avatar Feb 19 '25 16:02 kardelw1409

Fixed by https://github.com/OData/AspNetCoreOData/pull/1378 Test: TestComputeWithSubstringAsync (test\Microsoft.AspNetCore.OData.E2E.Tests\DollarApply\DollarApplyTests.cs)

gathogojr avatar Mar 18 '25 09:03 gathogojr