OData / OData/AspNetCoreOData

Where a navigation property is specified in $select, the corresponding navigation link is not represented in the response

Open
#944 3 comments 0 reactions 2 assignees View on GitHub

@gathogojr is already working on this.

Since May 30, 2023.

bug
Dominant language
C#
Stars
505
Forks
186
PR merge metrics
No merged PRs in 30d

Description

Assemblies affected
ASP.NET Core OData 8.2.0

Describe the bug
Where a navigation property is specified in $select, the corresponding navigation link is not represented in the response.
https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionselect

Reproduce steps
Build a simple OData service as follows:

// Data model
public class Customer
{
    public int Id { get; set; }
    public List<Order>? Orders { get; set; }
}

public class Order
{
    public int Id { get; set; }
}

// Controller
public class CustomersController
{
    private static readonly List<Customer> customers = new List<Customer>(
        Enumerable.Range(1, 2).Select(idx => new Customer
        {
            Id = idx,
            Orders = new List<Order>(
                Enumerable.Range(1, 2).Select(dx => new Order
                {
                    Id = dx
                }))
        }));

    [EnableQuery]
    public ActionResult<IEnumerable<Customer>> Get()
    {
        return customers;
    }
}

// Edm model and service configuration
using Microsoft.AspNetCore.OData;
using Microsoft.OData.ModelBuilder;

var builder = WebApplication.CreateBuilder(args);

var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Customer>("Customers");
modelBuilder.EntitySet<Order>("Orders");

builder.Services
    .AddControllers()
    .AddOData(
        options => options.EnableQueryFeatures().AddRouteComponents(
            model: modelBuilder.GetEdmModel()));

var app = builder.Build();

app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());

app.Run();

Data Model
Included in Reproduce steps

EDM (CSDL) Model

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="NS.Models" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="Customer">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <NavigationProperty Name="Orders" Type="Collection(NS.Models.Order)" />
            </EntityType>
            <EntityType Name="Order">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
            </EntityType>
        </Schema>
        <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityContainer Name="Container">
                <EntitySet Name="Customers" EntityType="NS.Models.Customer">
                    <NavigationPropertyBinding Path="Orders" Target="Orders" />
                </EntitySet>
                <EntitySet Name="Orders" EntityType="NS.Models.Order" />
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

Request/Response
Request:

http://localhost:5237/Customers?$select=Orders

Response:

{
    "@odata.context": "http://localhost:5237/$metadata#Customers(Orders)",
    "value": [
        {},
        {}
    ]
}

Expected behavior
The empty braces should contain the corresponding navigation links

{
    "@odata.context": "http://localhost:5237/$metadata#Customers(Orders)",
    "value": [
        {"Orders@odata.navigationLink":"http://localhost:5237/Customers/1/Orders"},
        {"Orders@odata.navigationLink":"http://localhost:5237/Customers/2/Orders"}
    ]
}

Additional context
https://github.com/OData/AspNetCoreOData/blob/ea4e79ce3a16238f12f55ca34c23a46cc01e291c/src/Microsoft.AspNetCore.OData/Query/Expressions/SelectExpandBinder.cs#L676 We should process navigation properties in the $select where they don't also appear in the $expand

Bug is reproducible is 7.x - Port fix.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.