c# - 嵌套 $expands 的 Asp.net WebApi OData V4 问题
问题描述
我有一个OData V4
结束Asp.net WebApi
(OWIN
)。
一切都很好,除非我尝试查询 4-level $expand
。
我的查询看起来像:
http://domain/entity1($expand=entity2($expand=entity3($expand=entity4)))
我没有收到任何错误,但我的回复中没有预测最后一次展开。
更多信息:
- 我已经设置
MaxExpandDepth
为 10。 - 我所有的实体都是
EntitySets
. - 我正在使用
ODataConventionModelBuilder
. - 我打开了一个 SQL 分析器,可以看到查询(和结果)是正确的。这是执行查询后发生的一些过滤器。
- 我在网上搜索并没有找到任何合适的东西。
- 我尝试了不同的实体 4 级别
$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);
}
序列化值包含 entity4。
我仍然不知道是哪个组件删除了管道中的 entity4。
编辑#2:
我一遍又一DefaultODataSerializerProvider
遍地创建了一个适配器ODataEdmTypeSerializer's
。我看到在此过程中$expand
存在 for entity4,并且当ODataResourceSerializer.CreateNavigationLink
在该 navigationProperty (entity4) 上调用该方法时,它返回 null。
我已经跳到源代码中,我可以看到SerializerContext.Items
它的项目中不包含 entity4 并且SerializerContext.NavigationSource
为空。
具体来说,我使用的是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;
}
所以我明白我的问题出在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();
推荐阅读
- ios - 如何根据铭文的长度设置布局锚?
- javascript - 如何在 Windows 上使用 JACK 的节点绑定将 electron.js 应用程序的音频路由到 Zoom 或 Google Meet?
- c - 无法从c程序编写的文本文件中读取数据
- google-chrome - chrome.downloads.download 永远不会启动,但没有错误
- java - 关于java Scanner的一些问题
- wordpress - 添加简码时未定义 WordPress 功能
- android - 如何在颤振上从用户发送电子邮件给管理员?
- git - Github 阻止推送到远程
- facebook - Facebook 图表添加链接
- r - 如何使用从 R 中的 rgl 包中提取的 as.mesh3d 函数中的 LiDAR 点创建 3D 网格