OData v4 Web API 2.2深层扩展无法正常工作

时间:2015-02-12 21:59:31

标签: asp.net-web-api odata

情况

我正在尝试将“项目”扩展到三个级别:

Item.Product.Model.Type

所以我称之为嵌套查询选项url:

http://xxx/api/Items?$扩大=产品($扩大=模型($扩大=类型))

我收到一条警告,表示已达到最大深度2,因此我将建议的MaxExpansionDepth属性设置为3.但是,不会返回“Type”属性!这由this SO question

涵盖

然后我查看official OData V4 standard,它说我应该在扩展选项中使用斜杠,如下所示:

http://xxx/api/Items?$扩大=产品/型号/类型

但这让我错误地说:

  

URI中指定的查询无效。找到遍历多个导航属性的路径。请重新调整查询,使每个展开路径仅包含类型段和导航属性。

这个SO answer涵盖的内容,但答案与官方OData文档相矛盾。无论如何,这甚至意味着什么。

问题

使用OData v4和Web API 2.2深度级别的$ expand查询选项的官方,标准和工作方式是什么

1 个答案:

答案 0 :(得分:8)

在聊天中与Jerther合作之后,我们将问题缩小到未标记为包含导航的扩展属性。因此,OData框架正在删除它们,因为它们没有定义相应的实体集。更新模型以专门声明包含似乎已解决了问题。

可以通过多种方式指定包含,具体取决于所使用的模型构建器。对于ODataConventionModelBuilder,您可以将System.Web.OData.Builder.ContainedAttribute添加到相关媒体中,而对于ODataModelBuilder,您可以使用ContainsMany<T>上的EntityTypeConfiguration方法包含类的实例。

此外,目前,级联展开将停止复杂类型包含实体类型的位置。

<强>更新

在EntitySet工作时定义链中的所有类型。

builder.EntitySet<Item>("Items");
builder.EntitySet<Product>("Products");
builder.EntitySet<Model>("Models");
builder.EntitySet<Type>("Types");

似乎将它们定义为EntityType是不够的。

见这里:https://github.com/OData/WebApi/issues/226

原始答案

我试过责备你的情况而不能。您的行动中是否可能没有设置“类型”?这是我的小repro

public class ItemsController : ODataController
{
    [HttpGet]
    [EnableQuery(MaxExpansionDepth = 10)]
    [ODataRoute("/Items")]
    public IHttpActionResult GetItems()
    {
        return this.Ok(CreateItem());
    }

    private Item CreateItem()
    {
        return new Item
        {
            Id = 1,
            Products = new Product[]
            {
                new Product
                {
                    Id = 2,
                    Models = new Model[]
                    {
                        new Model
                        {
                            Id = 3,
                            Types = new MyType[]
                            {
                                new MyType
                                {
                                    Id = 4,
                                },
                            },
                        },
                    },
                },
            },
        };
    }
}

当使用 / Items?$ expand = Products($ expand = Models($ expand = Types))调用时,会产生以下结果:

{
    "@odata.context": "http://localhost:9001/$metadata#Items/$entity",
    "Id": 1,
    "Products@odata.context": "http://localhost:9001/$metadata#Items(1)/Products",
    "Products": [{
        "Id": 2,
        "Models@odata.context": "http://localhost:9001/$metadata#Items(1)/Products(2)/Models",
        "Models": [{
            "Id": 3,
            "Types@odata.context": "http://localhost:9001/$metadata#Items(1)/Products(2)/Models(3)/Types",
            "Types": [{
                "Id": 4
            }]
        }]
    }]
}