WebApi
WebApi copied to clipboard
MaxExpansionDepth = 0 appears to have no effect
Copied form https://github.com/OData/odata.net/issues/860
Setting the MaxExpansionDepth to 0 appears to have no effect. Testing parent-child database classes yields the same result as not setting this attribute with: ?$expand=x($levels=max). Also when trying to set $levels to a number higher than default for example the following error is given: "Value cannot be null. Parameter name: value" suggesting it is replaced when higher than default.
Setting MaxExpansionDepth to, for example, 10 solves the problem. EDIT: Setting to 10 solves the error from appearing, but the JSON output is still a maximum of 3 levels deep! Even though the query being executed actually fetches the necessary data (confirmed by EF query logging).
Assemblies affected
Latest NuGet Microsoft.AspNet.Odata.
Reproduce steps
Create a class with parent-child relation. Set MaxExpansionDepth of the controller to 0. Notice that the expansion only works until the default allowed levels.
Expected result
I would expect setting MaxExpansionDepth = 0 would allow me to go as deep as I want in a class with parent-child relation, until the parent or child is null.
At least to me this is the result I would expect when looking at the documentation and attribute property summary.
See documentation: "Cyclic navigation properties (whose target type is identical or can be cast to its source type) can be recursively expanded using the special $levels option. The value of the $levels option is either a positive integer to specify the number of levels to expand, or the literal string max to specify the maximum expansion level supported by that service."
And attribute property summary: "Gets or sets the max expansion depth for the $expand query option. To disable the maximum expansion depth check, set this property to 0."
Actual result
MaxExpansionDepth = 0 does not disable the MaxExpansionDepth check.
Additional detail
Optional, details of the root cause if known. Delete this section if you have no additional details to add.
@xuzhg Is it possible to have an update on this?
@xuzhg Any update here?
@xuzhg @robward-ms The biggest issue here is that when expanding anything more than 3 levels the JSON output does not return this information. Would it be possible to get some feedback here?
I was faced with a similar problem. In my case, the problem was that the property was containment navigation property.
Request: http://localhost:63773/ODataExample/Users?$expand=Orders($expand=OrderPositions($expand=Products($expand=Parameters)))
builder.EntitySet<User>("Users");
builder.EntitySet<Order>("Orders");
builder.EntitySet<OrderPosition>("OrderPositions");
builder.EntitySet<Product>("Products");
builder.EntityType<User>()
.Expand(10, nameof(User.Orders))
// The property will be marked as containment navigation property
// and expanding anything more than 3 levels the JSON output does not return information
.ContainsMany(x => x.Orders);
builder.EntityType<Order>()
.Expand(10, nameof(Order.OrderPositions));
builder.EntityType<OrderPosition>()
.Expand(10, nameof(OrderPosition.Products));
builder.EntityType<Product>()
.Expand(10, nameof(Product.Parameters));
<EntityType Name="User">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int64" Nullable="false"/>
<Property Name="Name" Type="Edm.String"/>
<NavigationProperty Name="Orders" Type="Collection(ODataExample.Model.Order)" ContainsTarget="true"/>
</EntityType>
But If the property is not marked as ContainsTarget, the response contains the data nested at level 4.
If needed I can provide a sample project.
@flibustier7seas I would appreciate a sample project by you.
@bdebaere https://github.com/flibustier7seas/odata-example
@flibustier7seas Thank you for the sample. If I replace the code mentioned in your readme to the code below it keeps working. Do you have an idea why?
builder.EntityType<User>()
.Expand(10)
//.Expand(10, nameof(User.Orders))
// The property will be marked as containment navigation property
// and expanding anything more than 3 levels the JSON output does not return information
//.ContainsMany(x => x.Orders)
;
@bdebaere In this case you set all properties expandable with maximum depth of expand result of this structural type.
builder.EntityType<User>()
.Expand(10)
//.Expand(10, nameof(User.Orders))
// The property will be marked as containment navigation property
// and expanding anything more than 3 levels the JSON output does not return information
//.ContainsMany(x => x.Orders)
;
Wher use Expand(10, nameof(User.Orders)), you set only Orders property expandable with maximum depth of expand result.
I ran into the same problem. MaxExpansionDepth does not have any effect at all.
The following steps did not fix this:
- Migrating from .NET Core 3.1 to .NET 5.0
- Migrating OData-Libraries Microsoft.AspNetCore.OData to 8.0.0-preview3
Whatever value is passed to EnableQueryAttribute, it does not change the behavior:
[EnableQuery(MaxExpansionDepth = int.MaxValue)]
The method Expand does not exist on EntityTypeConfiguration. https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnet.odata.builder.entitytypeconfiguration?view=odata-aspnetcore-7.0 Not sure if it has been an extension method but if it has been, i am absolutley clueless where it has been moved. But the following did not work on the previous version, that i have been using and on 8.0.0-preview3 i cannot find it:
var order = builder.EntitySet<Order>(ResourceEnum.Orders.ToString());
order.EntityType.Expand(10);
builder.EntityType<OrderPosition>().Expand(10);
builder.EntityType<OrderDetail>().Expand(10);
The following OData-Query-Options should return expanded Orders that got Positions with Details with an Item and a Store on the Detail but Item and Store are not returned. root/Orders?$top=10&$expand=Position($expand=Detail($expand=Item,Store))&$orderby=Id desc
{
"Id": 1407,
"No": 795250,
"OrderDate": "2020-11-03T00:00:00+01:00",
"SupplierId": 4103,
"Position": [
{
"Id": 11469,
"PositionNo": 1,
"ArticleId": 132967,
"DeliveryDateFrom": "2020-11-04T00:00:00+01:00",
"DeliveryDateTo": "2020-11-04T00:00:00+01:00",
"CustomerId": 5224,
"OrderId": 1407,
"Detail": [
{
"Id": 46411,
"Quantity": 1.00,
"DeliveredQuantity": 1.00,
"PP": 22.00000,
"ListPP": 22.00000,
"DiscountPP": 0.00000,
"SP": 39.00000,
"OfferPrice": 39.00,
"ItemId": 262191,
"OrderPositionId": 11469,
"StoreId": 4
}
]
}
]
}
Has anyone found a solution to this ?