Skip to content

Ambiguous default get with composite OData key #1138

@pycxu

Description

@pycxu

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Controller

namespace Repro.Controllers
{
    public class Test
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }

    public class TestController : ODataController
    {
        protected IQueryable<Test> DataSource => new List<Test>
        {
            new Test { Id = 0, Name = "0", Description = "0" },
            new Test { Id = 1, Name = "1", Description = "1" },
            new Test { Id = 2, Name = "2", Description = "2" },
            new Test { Id = 3, Name = "3", Description = "3" }
        }.AsQueryable();

        [EnableQuery(MaxExpansionDepth = 6)]
        public SingleResult<Test> Get([FromODataUri] int key)
        {
            return SingleResult.Create(
                DataSource.Where(r => r.Id == key)
            );
        }

        [EnableQuery(MaxExpansionDepth = 6)]
        public virtual IActionResult Get()
        {
            return Ok(DataSource);
        }
    }
}

Single Key Configuration

    public class ModelConfiguration : IModelConfiguration
    {
        public void Apply(ODataModelBuilder builder, Asp.Versioning.ApiVersion apiVersion, string routePrefix)
        {
            builder.EntitySet<Test>("Test").EntityType.HasKey(e => e.Id);
        }
    }

Single Key Endpoints

GET | odata/v{version:apiVersion}/Test({key})
GET | odata/v{version:apiVersion}/Test/{key}
GET | odata/v{version:apiVersion}/Test

Composite Key Configuration

    public class ModelConfiguration : IModelConfiguration
    {
        public void Apply(ODataModelBuilder builder, Asp.Versioning.ApiVersion apiVersion, string routePrefix)
        {
            builder.EntitySet<Test>("Test").EntityType.HasKey(e => new { e.Id, e.Name });
        }
    }

Composite Key Endpoints

GET | odata/v{version:apiVersion}/Test
GET | odata/v{version:apiVersion}/Test/$count
GET | odata/v{version:apiVersion}/Test
GET | odata/v{version:apiVersion}/Test/$count

Why do Get([FromODataUri] int key) and Get() have the same endpoint here?
It seems that composite key entity type configuration is not working. How to fix this?

Expected Behavior

When single key is used, GET http://localhost:57464/odata/v1.0/Test?$count=true&$top=2 hits the Get() method as expected.

However, if composite key is used, GET http://localhost:57464/odata/v1.0/Test?$count=true&$top=2 seems to hit Get([FromODataUri] int key) if this method appears before Get().

From the /$data debug endpoints, they also look identical. Does that mean the order of the two method matter??

I would expect that when no key is used e.g. /Test, the Get() method should always be hit whether single or composite key is used:

Key Type Request Example Expected Method
Single Key GET /odata/v1.0/Test?$count=true&$top=2 Get() (collection)
  GET /odata/v1.0/Test(1) Get([FromODataUri] int key) (single)
Composite GET /odata/v1.0/Test?$count=true&$top=2 Get() (collection)
  GET /odata/v1.0/Test(Id=1,Name='abc') Get([FromODataUri] int keyId, string keyName)

Steps To Reproduce

OData Ambiguous Detault Get.zip

I also tried the ODataBasicExample: pycxu@28067cb

Exceptions (if any)

The current setup worked for us with the MapVersionedODataRoutes way of configuring OData.

Repro - old.zip

Above repro will work for both single and composite key.

.NET Version

.Net 8

Anything else?

Not sure if this is a bug or I'm not setting up versioned OData properly.

Also I'm not able to make composite key work at all. I could not find any composite key examples by searching repo:dotnet/aspnet-api-versioning .HasKey( in this repo.

Any help would be appreciated, thanks.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions