ApiController和ODataController在暴露DTOs时有什么区别?

24

请问有人能解释一下我何时应该继承我的控制器从 ODataController 而不是 ApiController ?

这个问题是由于 ApiController 返回的结果可以用 OData 查询进行筛选。

如果我将 QueryableAttribute 应用于控制器的方法,即使操作返回 IEnumerable,查询也会被处理。

但是如果没有这个属性,但调用了 config.EnableQuerySupport(),只有当方法返回 IQueryable 时才会处理查询。

我认为这是不一致的行为。WebAPI 的文档和示例表明控制器必须继承自 ODataController。我有点困惑。

要么 ApiController “意外地”支持了 OData 协议的部分(至少是 $ skip、$filter 和 $top)。要么这是经过设计的,我需要 ODataController 来完整支持 OData。

真正的问题是我的服务公开了 DTO,而不是 POCO。可能没有一对一的映射。需要将针对 DTO 的 OData 查询转换为针对 POCO 的 EF 查询。

现在只是玩 OData。我检索实体并将它们转换为 DTO。诚然,这不是从数据库获取所有实体的性能很好,但对于实验来说是可以容忍的。但如果需要返回客户端的只是一些经过筛选的子集,就绝对没有必要返回所有实体。

使用 ApiController 和 Querayble 属性,OData 查询可以直接工作。但上述不一致性让我觉得自己做错了什么。


3
我认为这是因为它实现了附加功能,比如元数据,使得WCF Data Services客户端可以使用:http://sravi-kiran.blogspot.co.nz/2013/08/ConsumingWebApiODataFromNetAndJavaScriptClientApplications.html,http://blogs.msdn.com/b/webdev/archive/2013/01/29/getting-started-with-asp-net-webapi-odata-in-3-simple-steps.aspx,http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api 。Web API(带有查询支持)于2012年1月发布,而Web API OData于2013年1月发布,因此我认为你说的“我需要ODataController来完全支持OData”以满足OData规范是正确的。 - Michael
2个回答

14

有人能解释一下我何时应该从ODataController继承我的控制器,何时应该从ApiController继承吗?

如果您想公开遵守OData协议的端点,则应该从ODataController继承。如果您想做其他事情,例如REST端点,则应该从ApiController继承。

只应用WebAPI OData框架的某些部分,而不是其他部分,可能不是一个好主意。在某些情况下可能会有效,但在其他情况下可能效果不佳。例如,您可能会获得查询支持,但$metadata端点可能不会生成(这只是猜测,实际症状可能不同)。

听起来您已经在使用EntityFramework。我知道有很多样例可以展示如何将其公开为OData端点。

如果出于某些原因您不想这么做,您可以自己实现查询。 此教程 简要介绍了这个过程,但其要点在于向您的操作添加类型为 ODataQueryOptions<T> 的参数,并使用它上面的方法来过滤结果集。然而,为所有可能的 OData 查询生成良好的数据库查询可能很繁琐,所以如果可能的话,请避免这样做。

谢谢。我修改了我的问题的措辞,希望它变得更加清晰明了。 - Pavel Voronin
我认为如果你将控制器分开放在它们自己的目录中可能是个好主意。比如在你的Controllers文件夹下创建一个API文件夹和一个OData文件夹。使用OData的一个优点是,你不必为每个请求的项创建一个新的硬编码linq查询;它非常适用于查询单个实体(而不是连接实体)。查询url会自动生成linq表达式。通过消除添加新linq查询的需要,你可以避免项目的代码维护和开销。 - sksallaj
1
我会在处理复杂的实体关系时使用APIController,而在处理简单的单个实体关系时使用OData。 - sksallaj

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接