I have a OData V4
over Asp.net WebApi
(OWIN
).
Everything works great, except when I try to query a 4-level $expand
.
My query looks like:
http://domain/entity1($expand=entity2($expand=entity3($expand=entity4)))
I don't get any error, but the last expand isn't projected in my response.
More info:
MaxExpandDepth
to 10.EntitySets
.ODataConventionModelBuilder
.$expands
and they didn't work as well.Edit:
I've overridden the OnActionExecuted
:
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
var objectContent = actionExecutedContext.Response.Content as ObjectContent;
var val = objectContent.Value;
var t = Type.GetType("System.Web.OData.Query.Expressions.SelectExpandWrapperConverter, System.Web.OData");
var jc = Activator.CreateInstance(t) as JsonConverter;
var jss = new JsonSerializerSettings();
jss.Converters.Add(jc);
var ser = JsonConvert.SerializeObject(val, jss);
}
The serialized value contains entity4.
I still have no idea what component removes entity4 in the pipe.
Edit #2:
I've create an adapter over DefaultODataSerializerProvider
and over all the other ODataEdmTypeSerializer's
. I see that during the process the $expand
for entity4 exists and when the ODataResourceSerializer.CreateNavigationLink
method is called on that navigationProperty (entity4) then it returns null.
I've jumped into the source code and I could see that the SerializerContext.Items
doesn't include the entity4 inside it's items and the SerializerContext.NavigationSource
is null.
To be specific with versions, I'm using System.Web.OData, Version=6.1.0.10907
.
Ok, so I noticed the problem was due to the fact that my navigation property was of type EdmUnknownEntitySet
and the navigation property lookup returns null (source code attached with an evil TODO..):
/// <summary>
/// Finds the entity set that a navigation property targets.
/// </summary>
/// <param name="property">The navigation property.</param>
/// <returns>The entity set that the navigation propertion targets, or null if no such entity set exists.</returns>
/// TODO: change null logic to using UnknownEntitySet
public override IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty property)
{
return null;
}
So I understood my problem was with the EdmUnknownEntitySet
.
I digged into the code and saw that I needed to add the ContainedAttribute
to the my navigation properties.
Since my solution is kind of a Generic repository, I've added it in the Startup for All navigation properties:
builder.OnModelCreating = mb => mb.StructuralTypes.SelectMany(s => s.NavigationProperties
.Where(np => np.Multiplicity == EdmMultiplicity.Many)).Distinct().ForEach(np => np.Contained());
//......
var model = builder.GetEdmModel();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With