Assemblies affected
Microsoft.AspNetCore.OData all of v8 and v9 as far as I can see.
Describe the bug
Run the ODataRoutingSample.
In the Customers controller, we return an IActionResult with an IQueryable:
public IActionResult Get()
{
return Ok(GetCustomers());
}
If you call:
http://localhost:5000/v1/Customers
You will get an OData response:
{
"@odata.context": "http://localhost:5001/v1/$metadata#Customers",
"value": [
{
"Id": 1,
"Name": "Jonier",
"FavoriteColor": "Red",
"Amount": 3,
"HomeAddress": {
"City": "Redmond",
"Street": "156 AVE NE"
},
"FavoriteAddresses": [
{
"City": "Redmond",
"Street": "256 AVE NE"
},
{
"City": "Redd",
"Street": "56 AVE NE"
}
]
},
{
"Id": 2,
"Name": "Sam",
"FavoriteColor": "Blue",
"Amount": 6,
"HomeAddress": {
"@odata.type": "#ODataRoutingSample.Models.CnAddress",
"City": "Bellevue",
"Street": "Main St NE",
"Postcode": "201100"
},
"FavoriteAddresses": [
{
"City": "Red4ond",
"Street": "456 AVE NE"
},
{
"City": "Re4d",
"Street": "51 NE"
}
]
}
],
"@odata.nextLink": "http://localhost:5001/v1/Customers?$skip=2"
}
But if you use an aggregate function:
http://localhost:5000/v1/Customers?$apply=groupby((FavoriteColor))
You will get a non-OData response:
[
{
"FavoriteColor": 0
},
{
"FavoriteColor": 1
}
]
However, if you return an IQueryable<T> directly and call the same aggregate query URL:
public IQueryable<Customer> Get()
{
return GetCustomers().AsQueryable();
}
You get a proper OData response for the aggregate query:
{
"@odata.context": "http://localhost:5001/v1/$metadata#Customers(FavoriteColor)",
"value": [
{
"@odata.id": null,
"FavoriteColor": "Red"
},
{
"@odata.id": null,
"FavoriteColor": "Green"
}
],
"@odata.nextLink": "http://localhost:5001/v1/Customers?$apply=groupby%28%28FavoriteColor%29%29&$skip=2"
}
Futher notes
If you return IQueryable only (not typed):
public IQueryable Get()
{
return GetCustomers().AsQueryable();
}
You never get an OData response.
If you return IActionResult, do an aggregate query AND specify the DeclaredType in an OkObjectResult, you get the correct OData response back:
public IActionResult Get()
{
return new OkObjectResult(GetCustomers())
{
DeclaredType = typeof(IQueryable<Customer>)
};
}
Reproduce steps
Run the ODataRoutingSample and see the above steps.
Data Model
ODataRoutingSample - EdmModelBuilder.GetEdmModelV1()
EDM (CSDL) Model
NA
Request/Response
See above
Expected behavior
It should produce an OData response, even with an aggregate query returning an IActionResult.
Screenshots
NA
Additional context
NA
Assemblies affected
Microsoft.AspNetCore.ODataall of v8 and v9 as far as I can see.Describe the bug
Run the
ODataRoutingSample.In the
Customerscontroller, we return anIActionResultwith anIQueryable:If you call:
http://localhost:5000/v1/CustomersYou will get an OData response:
{ "@odata.context": "http://localhost:5001/v1/$metadata#Customers", "value": [ { "Id": 1, "Name": "Jonier", "FavoriteColor": "Red", "Amount": 3, "HomeAddress": { "City": "Redmond", "Street": "156 AVE NE" }, "FavoriteAddresses": [ { "City": "Redmond", "Street": "256 AVE NE" }, { "City": "Redd", "Street": "56 AVE NE" } ] }, { "Id": 2, "Name": "Sam", "FavoriteColor": "Blue", "Amount": 6, "HomeAddress": { "@odata.type": "#ODataRoutingSample.Models.CnAddress", "City": "Bellevue", "Street": "Main St NE", "Postcode": "201100" }, "FavoriteAddresses": [ { "City": "Red4ond", "Street": "456 AVE NE" }, { "City": "Re4d", "Street": "51 NE" } ] } ], "@odata.nextLink": "http://localhost:5001/v1/Customers?$skip=2" }But if you use an aggregate function:
http://localhost:5000/v1/Customers?$apply=groupby((FavoriteColor))You will get a non-OData response:
[ { "FavoriteColor": 0 }, { "FavoriteColor": 1 } ]However, if you return an
IQueryable<T>directly and call the same aggregate query URL:You get a proper OData response for the aggregate query:
{ "@odata.context": "http://localhost:5001/v1/$metadata#Customers(FavoriteColor)", "value": [ { "@odata.id": null, "FavoriteColor": "Red" }, { "@odata.id": null, "FavoriteColor": "Green" } ], "@odata.nextLink": "http://localhost:5001/v1/Customers?$apply=groupby%28%28FavoriteColor%29%29&$skip=2" }Futher notes
If you return
IQueryableonly (not typed):You never get an OData response.
If you return
IActionResult, do an aggregate query AND specify theDeclaredTypein anOkObjectResult, you get the correct OData response back:Reproduce steps
Run the
ODataRoutingSampleand see the above steps.Data Model
ODataRoutingSample-EdmModelBuilder.GetEdmModelV1()EDM (CSDL) Model
NA
Request/Response
See above
Expected behavior
It should produce an OData response, even with an aggregate query returning an
IActionResult.Screenshots
NA
Additional context
NA