【问题标题】:Why doesn't my oData response have navigation properties为什么我的 oData 响应没有导航属性
【发布时间】:2021-09-09 16:57:31
【问题描述】:

如果您查看以下示例 oData 提要,您会看到包含“子”项的导航属性,告诉您要遵循哪个 URL:

http://services.odata.org/OData/OData.svc/Suppliers?$format=json

例如,供应商 0 具有产品的导航属性。 这链接到该供应商的产品列表。

http://services.odata.org/OData/OData.svc/Suppliers(0)/Products?$format=json


我正在尝试对 ODataConventionModelBuilderEntitySetController<Product> 做同样的事情,这样当我请求 oData/Product(0) 时,它会向我显示产品的“功能”:

我这样创建我的模型(基于GetImplicitEdmModel sample

     // odata
     ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
     modelBuilder.EntitySet<RRStoreDB.Models.Product>("Product");
     modelBuilder.EntitySet<RRStoreDB.Models.ProductFeature>("ProductFeature");

     Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel();
     config.Routes.MapODataRoute("ODataRoute", "odata", model);

我为 WebAPI 创建了一个控制器:

public class  ProductController : EntitySetController<Product, int>
{
    RRStoreDBContext _db = new RRStoreDBContext();


    [Queryable]
    public override IQueryable<DProduct> Get()
    {
        return _db.Products.AsQueryable();
    }

    public ICollection<ProductFeature> GetProductFeatures(int key)
    {
        Product product = _db.Products.FirstOrDefault(p => p.ProductId == key);
        if (product == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        return product.ProductFeatures;
    }
}

当我实际调用我的子属性的 URL 时,它会起作用并为我提供正确的功能列表:

 /oData/Products(18)/ProductFeatures

但是,我希望/oData/Products(18) 中的导航属性指向此。

我需要做些什么才能让它出现。 This article 说它是自动的,但我没有看到它们:

ODataConventionModelBuilder,通常推荐使用 ODataModelBuilder,将自动推断继承 没有显式配置的层次结构。然后一旦 层次结构被推断,它也会推断属性和导航 属性也。这使您可以编写更少的代码,专注于在哪里 你偏离了我们的约定。

【问题讨论】:

  • 我找到了一个基本上可以完成我正在做的事情的示例 - 而且它也没有导航属性 - 我该如何启用它们 - 还是不支持? aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/…
  • 我想我已经正式放弃了。 oData 太复杂了!
  • 嗨@Simon_Weaver,我和你完全一样,但我得到的错误是:Not implemented, This service doesn't support OData requests in the form '~/entityset/key/unresolved'.你能解决这个问题吗?

标签: wcf-data-services odata asp.net-web-api


【解决方案1】:

我认为问题在于您要求application/json。 Web API OData 中的application/json 指向 json light,这是最新的 OData json 表示,旨在减少响应有效负载大小并从响应中修剪不必要/冗余的元数据。为了比较,尝试获取带有接受标头application/json;odata=verbose 的url ~/oData/Products(18)

现在,json light 背后的想法是,如果由于链接遵循约定而可以计算链接,则不会将其放入响应中。导航链接/oData/Products(18)/ProductFeatures 就是一个很好的例子。它遵循 OData uri 约定。

OData json light 有 3 种模式,minimalmetadata(默认)、fullmetadata 和 nometadata。这些名称本身就是解释性的。如果您希望链接在线,请发送带有接受标头application/json;odata=fullmetadata 的请求。

请参阅此document 以了解有关 json light 的更多信息。

【讨论】:

  • 太棒了——做到了!从难以设置接受标头的浏览器调用时,有什么方法可以强制使用完整的 JSON
  • 在 URL 中替换 $format=json,试试 $format=application/json;odata=fullmetadata。如果您从 javascript 使用 OData,您可能对 datajs 库感兴趣。据我所知,datajs 在后台请求 fullmetadata,但它会为您抽象出其中的一些细节。
  • Web API OData 不支持 $format 开箱即用。通过使用消息处理程序很容易添加对 $format 的支持。我有一个样品here
猜你喜欢
  • 2020-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
相关资源
最近更新 更多