【问题标题】:Returning Nested Objects on .NET API using OData使用 OData 在 .NET API 上返回嵌套对象
【发布时间】:2017-08-30 05:35:17
【问题描述】:

我正在开发一个使用 OData 的 .NET API,我目前在将嵌套对象返回给客户端时遇到问题。

一切似乎都在工作,即使我在响应之前在控制器上设置了一个断点。我可以看到将要返回的所有信息都正确填充的 Vendor 对象,但是当我查看客户端收到的 JSON 响应时,它只有原始类型和枚举,其他所有作为另一个对象的属性都不会被序列化到 JSON 结果。

public class Vendor : IEntity
{
    public virtual int Id { get; set; }
    public virtual VendorAddress PrimaryAddress { get; set; }
    public virtual string VendorName { get; set; }
}

public class VendorAddress : IEntity
{
    public virtual int Id { get; set; }
    public virtual Vendor Vendor { get; set; }
    public virtual Address Address { get; set; }

}

 public class Address : IEntity
{
    public virtual int Id { get; set; }   
    public virtual string Line1 { get; set; }
    public virtual string Line2 { get; set; }     
    public virtual string Country { get; set; }
    public virtual string CountryCode { get; set; }
    public virtual string City { get; set; }
    public virtual string County { get; set; }
    public virtual string StateProvince { get; set; }
    public virtual string ZipCode { get; set; }    
}   

 public SingleResult<Vendor> Get([FromODataUri] int key)
{
    var result = _repository.Query<Vendor>().Where(a => a.Id == key);
    return SingleResult.Create(result);
}

基本上我想返回供应商信息,包括 JSON 结果中的 PrimaryAddress/Address 信息,但似乎无法弄清楚如何。

【问题讨论】:

  • 你是从ODataController派生的吗? _repository 是什么?也尝试从未加载的属性中删除virtual
  • @Alonso:您编写了 .NET API。我猜你的意思是 ASP.NET Web API,对吧?!
  • @jpq:是的,它是一个 ASP.NET API
  • @T.S.我确实从 ODataController 派生,所有其他 OData 查询 url 东西,如 $count、$select 和其他东西似乎都正常工作。据我所知,无法删除虚拟原因,它们是使用 NHibernate 所必需的
  • 我想,我知道你的问题出在哪里。我只是针对实体框架编写了这样的服务。在 EF 中,我需要正确设置模型关系。例如,我看不到您的模型之间的关系在哪里?这是 hocus-pocus - OData 使用与实体框架相同的属性类。如果您在模型上设置这些属性(如[Key][ForeignKey]),Odata 模型构建器将创建所有需要的关系,并且您的 JSON 会正常运行。或者,您可以使用流畅的 Odata 语法映射它们。就我而言,因为我在 EF 模型中设置了映射,所以 OData 无需特殊映射即可工作

标签: c# json asp.net-web-api nhibernate odata


【解决方案1】:

VendorAddressAddress 是所谓的导航属性。 您可以在查询中使用$expand 来获取它们。 首先将 [EnableQuery] 添加到您的 Get 方法中

[EnableQuery]
public SingleResult<Vendor> Get([FromODataUri] int key)

然后尝试表单中的请求

<serviceUri>/Vendor(1)?$expand=VendorAddress
<serviceUri>/Vendor(1)?$expand=VendorAddress($expand=Address)

你必须添加行

config.Expand()

在你的

WebApiConfig.Register(HTTPConfiguration config)

方法。

这是一个测试服务的示例请求:

http://services.odata.org/TripPinRESTierService/People('russellwhyte')?$expand=BestFriend($expand=Trips)

还有更多信息供参考:http://www.odata.org/odata-services/

希望这会有所帮助。

【讨论】:

  • 非常感谢到目前为止的所有帮助,但是我仍在为此苦苦挣扎:(。我在 Controller 调用中添加了代码 [EnableQuery(MaxExpansionDepth = 3)] 代码,而且我设法做到了展开第一个导航属性但不使用 /Vendor(1)?$expand=primaryAddress 而是我使用 /api/v2/odata/Vendors?&$select=id,vendorName,primaryAddress&$expand =primaryAddress,从这个请求中我得到了 id 属性,但似乎无法扩展 primaryAddress 中的其他导航以实际获取我需要的地址信息
  • 好的,你能检查 $expand=PrimaryAddress/Address 而不是 $expand=PrimaryAddress($expand=Address)
猜你喜欢
  • 2014-03-22
  • 1970-01-01
  • 1970-01-01
  • 2020-01-26
  • 2013-09-25
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 2021-06-09
相关资源
最近更新 更多