asp.net-web-api - OData v4 Web API 2.2 深层扩展不起作用

标签 asp.net-web-api odata

情况

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

项目.产品.型号.类型

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

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

我收到一条警告,指出已达到最大深度 2,因此我将建议的 MaxExpansionDepth 属性设置为 3。但是,“Type”属性未返回! this SO question 涵盖了这一点

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

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

但这给了我一个错误提示:

The query specified in the URI is not valid. Found a path traversing multiple navigation properties. Please rephrase the query such that each expand path contains only type segments and navigation properties.

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

问题

使用 OData v4 和 Web API 2.2 进行深层 $expand 查询选项的官方、标准和工作方式是什么

最佳答案

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

可以通过多种方式指定包含,具体取决于所使用的模型构建器。以ODataConventionModelBuilder为例您可以添加System.Web.OData.Builder.ContainedAttribute到有问题的属性(property),而对于 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

原始答案

我尝试重现您的情况,但失败了。您的操作中是否可能未设置“类型”?这是我的小复制品

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
            }]
        }]
    }]
}

关于asp.net-web-api - OData v4 Web API 2.2 深层扩展不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28488639/

相关文章:

windows-phone-7 - 从 WP7 连接到 SQL Azure

OData 服务版本控制

wcf - IIS7 Post/Put/Patch/Delete WCF oData - 身份验证失败 401.3

odata - 如果 DTO 具有派生类,则使用 OData 选择的 Automapper 投影会抛出错误

asp.net-mvc-routing - 如何在MapHttpRoute中设置默认 namespace ?

c# - 当从另一个项目内部提供 api 时,如何在 Swashbuckle/Swaggerwork 中创建 url 路径?

c# - CORS 不适用于路线

null - 如何在odata响应中跳过空值?

asp.net - ASP.NET Web API 中除 IQueryable 之外的 OData 查询和类型

c# - 将 ASP.NET WebAPI Minimal 中的 Program.cs 与 Startup.cs 分开以进行集成测试