我正在使用Microsoft ASP.NET Web API 2.2 for OData v4。由于edmx中的循环引用,我不能使用ODataConventionModelBuilder,所以我使用ODataModelBuilder。
我的一个实体类型具有可选的NavigationProperty,可以像这样添加
var item = builder.EntityType<API.Item>();
...
item.HasOptional(a => a.Customer);
这会产生以下$元数据
<EntityType Name="Item">
...
<NavigationProperty Name="Customer" Type="XXX.API.Customer" />
...
浏览器当然在获取odata / Items的$ expand结果方面没有问题?$ expand = Customer 像这样
{"@odata.context":"http://localhost:5404/odata/$metadata#Items","value":
[
{"ItemId":15, ... "Customer":{"CustomerId":5,...}}
...
]
然而,当涉及到使用
的客户端C#应用程序时Microsoft.OData.Client.DataServiceQuery<Item> _items;
...
_items.Expand(i => i.Customer)
失败,出现以下异常:
编写JSON响应时,必须指定用户模型,并且必须将实体集和实体类型传递给ODataMessageWriter.CreateODataEntryWriter方法,或者必须在正在写入的ODataEntry或ODataFeed上设置ODataFeedAndEntrySerializationInfo。
但是,如果我将服务器型号更改为
var item = builder.EntityType<API.Item>();
...
item.ContainsOptional(a => a.Customer);
导致以下$元数据
<EntityType Name="Item">
...
<NavigationProperty Name="Customer" Type="XXX.API.Customer" ContainsTarget="true"/>
...
以下回复(注意第二个@ odata.context)
{"@odata.context":"http://localhost:5404/odata/$metadata#Items","value":
[
{
"ItemId":15, ...
"Customer@odata.context": "http://localhost:5404/odata/$metadata#Items(15)/Customer/$entity",
"Customer":{"CustomerId":5,...}}
...
]
客户端代码很好。展开就像魅力一样。
所以,正如我想的那样,这是因为第二个@ odata.context描述了嵌套对象。 当然,我可以使用ContainsOptional作为解决方法,但这似乎不适合做,因为“item”不包含“customer” - 它们在业务逻辑中是独立的。
这是OData核心库中的错误吗?或者,有没有办法强制Web API将@ odata.context包含在HasOptional属性中?
编辑:我已检查过最新版本7.4.0,现在它提供了稍微不同的错误:“无法计算ID,因为导航源”客户“无法解析为从模型中设置的已知实体。“但基本上,它是一样的。
答案 0 :(得分:0)
最后,我已经从MS客户端库切换到Simple OData Client https://github.com/object/Simple.OData.Client - 这是一种更容易使用的方式。