Webapi: Deep expand not working

Created on 19 Feb 2015  路  8Comments  路  Source: OData/WebApi

I'm trying to expand three levels and the third level is not serialized.

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

Types will not be returned even though MaxExpansionDepth attribute is set to 3, or even 4.

The issue seems to appear only in Web API. Using a WebApp works fine.

Here's a link to a sample project:
https://www.dropbox.com/s/xs0y4b92xv1pkh9/WebApplication2.7z?dl=0
run it and try:
http://XXX/api/Items?$expand=Products($expand=Models($expand=Types))

More details and a working WebApp here:
http://stackoverflow.com/questions/28488639/odata-v4-web-api-2-2-deep-level-expand-not-working

Most helpful comment

Just thought I would add a note on this as I just had the same problem ...
In my case I wanted to expand through a property that wasn't exposed as an entity on the model and it did that but only to the next level and not beyond despite all entities being defined properly beyond that.

something like ...

root {
   non model defined entity {
      entity {    <-- this gets shown
        entity 2 {  } <-- this doesn't
      }
   }
}

Hopefully this helps in some way

All 8 comments

We've found that the following fixes the problem for WebAPI:

  • add the [Contained] attribute to each property
  • define each property in the ODataModelBuilder: builder.EntityType().ContainsMany(m => m.Products);
  • not tested but probably works too, defining each property type as an entity set: builder.EntitySet("Products");

@Jerther We will close this issue. Ping us to re-open if any further issue. Thanks.

Closing this means to me that it is by design. If that's the case, is there an explanation for the different behavior between WebAPI and WebApp ?

@Jerther
Thanks for contacting us. We need to define each entity set, normally, in non-containment scenario. I added the following lines between the 2 //, and it worked:

c# var builder = new ODataConventionModelBuilder() { Namespace = "Default" }; builder.EntitySet<Item>("Items"); // builder.EntitySet<Product>("Products"); builder.EntitySet<Model>("Models"); builder.EntitySet<MyType>("Types"); // var model = builder.GetEdmModel();

If your intention is using Containment (spec), please follow brad's suggestion in StackOverflow.

About this issue, I do not see a difference among different hosting environments, e.g., SelfHost, OWIN, IIS.

By the way, also very welcome your contribution to the documentation of OData, e.g., OData Web API; though we have some documents for Convention Model Builder and unit tests etc. for Containment.

I've run into this same problem, however, only the switch to EntitySet seemed to work. Moreover, not all of my entities seem to be affected by this. Very hard to debug problem.

I suggest that an exception be thrown in the case that an Expand is requested and the service does not choose to expand it.

i tried second approach "define each property in the ODataModelBuilder: builder.EntityType().ContainsMany(m => m.Products);" but it didnt work

Just thought I would add a note on this as I just had the same problem ...
In my case I wanted to expand through a property that wasn't exposed as an entity on the model and it did that but only to the next level and not beyond despite all entities being defined properly beyond that.

something like ...

root {
   non model defined entity {
      entity {    <-- this gets shown
        entity 2 {  } <-- this doesn't
      }
   }
}

Hopefully this helps in some way

We've found that the following fixes the problem for WebAPI:

  • add the [Contained] attribute to each property
  • define each property in the ODataModelBuilder: builder.EntityType().ContainsMany(m => m.Products);
  • not tested but probably works too, defining each property type as an entity set: builder.EntitySet("Products");

All properties in the chain from the top most level (the root of the response object) must also have the [Contained] attribute for this to work.

Was this page helpful?
0 / 5 - 0 ratings