Ami*_*ich 10 c# odata asp.net-web-api
我有一个OData V4在Asp.net WebApi(OWIN).
一切都很好,除非我尝试查询4级$expand.
我的查询如下:
http://domain/entity1($expand=entity2($expand=entity3($expand=entity4)))
Run Code Online (Sandbox Code Playgroud)
我没有收到任何错误,但我的回复中没有预测最后一次展开.
更多信息:
MaxExpandDepth为10.EntitySets.ODataConventionModelBuilder.$expands,但它们也没有用.编辑:
我已经覆盖了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);
}
Run Code Online (Sandbox Code Playgroud)
序列化值包含entity4.
我仍然不知道哪个组件删除了管道中的entity4.
编辑#2:
我一遍DefaultODataSerializerProvider又一遍地创建了一个适配器ODataEdmTypeSerializer's.我看到在进程中,$expandfor entity4存在,当ODataResourceSerializer.CreateNavigationLink在该navigationProperty(entity4)上调用该方法时,它返回null.
我已经跳到了源代码中,我可以看到SerializerContext.Items它不包含entity4项中的entity4,并且SerializerContext.NavigationSource为null.
为了具体版本,我正在使用System.Web.OData, Version=6.1.0.10907.
好的,所以我注意到问题是由于我的导航属性是类型EdmUnknownEntitySet并且导航属性查找返回 null(源代码附加了一个邪恶的 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;
}
Run Code Online (Sandbox Code Playgroud)
所以我明白我的问题出在EdmUnknownEntitySet.
我深入研究了代码,发现我需要将ContainedAttribute加到我的导航属性中。
由于我的解决方案是一种通用存储库,因此我已将其添加到 Startup for All 导航属性中:
builder.OnModelCreating = mb => mb.StructuralTypes.SelectMany(s => s.NavigationProperties
.Where(np => np.Multiplicity == EdmMultiplicity.Many)).Distinct().ForEach(np => np.Contained());
//......
var model = builder.GetEdmModel();
Run Code Online (Sandbox Code Playgroud)