OData v4 Web API 2.2 level extension not working

Situation

I am trying to expand "Item" to three levels:

Item.Product.Model.Type

So, I call this variant of nested url requests:

http: // xxx / api / Items ? $ expand = Product ($ expand = Model ($ expand = Type))

We get a warning that the maximum depth of 2 has been reached, so I set the proposed MaxExpansionDepth attribute to 3. But then the Type property does not return! This is addressed by this SO issue.

Then I look at the official OData V4 standard , and it says that I should use slashes in the extension options, for example:

http: // xxx / api / Items ? $ expand = Product / Model / Type

But this gives me an error message:

The request specified in the URI is invalid. Found a path crossing several navigation properties. Please rephrase the query so that each extension path contains only type segments and navigation properties.

This answer to https://stackoverflow.com/a/26266161/ covers, but the answer contradicts the official OData doc. What does it mean even in any case.

Question

What is the official, standard, and working way to use the $ expand query option for deep layers with OData v4 and Web API 2.2.

+5
source share
1 answer

After working with Jerther in the chat, we narrowed down the problem to advanced properties that were not marked as contained in the navigation. As a result, the OData structure deleted them because they did not match the corresponding entity sets. Perhaps updating the model for a specific containment declaration has solved the problem.

The restriction can be specified in several ways, depending on which model the builder is used. In the case of ODataConventionModelBuilder you can add System.Web.OData.Builder.ContainedAttribute to the property in question, whereas for ODataModelBuilder you can use the ContainsMany<T> method for an EntityTypeConfiguration instance for the containing class.

In addition, the cascading extension will stop at the moment where the complex type contains the Entity type.

UPDATE:

Define all types in the chain as an EntitySet.

 builder.EntitySet<Item>("Items"); builder.EntitySet<Product>("Products"); builder.EntitySet<Model>("Models"); builder.EntitySet<Type>("Types"); 

It seems that defining them as EntityType not enough.

see here: https://github.com/OData/WebApi/issues/226

Original answer

I tried to reproduce your situation and could not. Is it possible that β€œTypes” are not set in your action? Here was my little review

 public class ItemsController : ODataController { [HttpGet] [EnableQuery(MaxExpansionDepth = 10)] [ODataRoute("/Items")] public IHttpActionResult GetItems() { return this.Ok(CreateItem()); } private Item CreateItem() { return new Item { Id = 1, Products = new Product[] { new Product { Id = 2, Models = new Model[] { new Model { Id = 3, Types = new MyType[] { new MyType { Id = 4, }, }, }, }, }, }, }; } } 

What when called with / Items? $ expand = Products ($ expand = Models ($ expand = Types)) led to the following:

 { "@odata.context": "http://localhost:9001/$metadata#Items/$entity", "Id": 1, " Products@odata.context ": "http://localhost:9001/$metadata#Items(1)/Products", "Products": [{ "Id": 2, " Models@odata.context ": "http://localhost:9001/$metadata#Items(1)/Products(2)/Models", "Models": [{ "Id": 3, " Types@odata.context ": "http://localhost:9001/$metadata#Items(1)/Products(2)/Models(3)/Types", "Types": [{ "Id": 4 }] }] }] } 
+6
source

Source: https://habr.com/ru/post/1213276/


All Articles