公开 DTO 时的 ApiController 与 ODataController
Posted
技术标签:
【中文标题】公开 DTO 时的 ApiController 与 ODataController【英文标题】:ApiController vs ODataController when exposing DTOs 【发布时间】:2013-08-16 11:36:49 【问题描述】:谁能解释我什么时候应该继承我的控制器表单ODataController
vs ApiController
?
问题是因为ApiController
返回的结果可以用OData查询过滤。
如果我将QueraybleAttribute
应用于控制器的方法,即使操作返回IEnumerable
,也会处理查询。
但是,如果没有此属性但调用 config.EnableQuerySupport()
,则仅当方法返回 IQueryable
时才会处理查询。
我认为这不是一致的行为。 WebAPI documentation and examples 暗示控制器必须从 ODataController 中初始化。我有点困惑。ApiController
accidentally
和部分支持 OData 协议的一部分(至少 $skip、$filter 和 $top)。或者这是设计使然,我需要 ODataController 来获得完整的 ODataSupport。
真正的问题是我的服务公开了 DTO,而不是 POCO。可能没有一对一的映射。需要将针对 DTO 的 OData 查询转换为针对 POCO 的 EF 查询。 现在只是玩 OData。我检索实体并将它们转换为 DTO。诚然,对于每个请求从数据库中获取所有这些请求的性能并不是很好,但对于实验却是可以容忍的。但是,如果它需要一些过滤的 DTO 子集,则绝对不需要将所有实体返回给客户端。 OData 查询开始使用 ApiController 和 Querayble 属性开箱即用,但前面提到的不一致让我觉得我做错了。
【问题讨论】:
我认为这是因为它实现了其他功能,例如允许使用 WCF 数据服务客户端的元数据:sravi-kiran.blogspot.co.nz/2013/08/…、blogs.msdn.com/b/webdev/archive/2013/01/29/…、asp.net/web-api/overview/odata-support-in-aspnet-web-api。 Web API(带查询支持)于 2012 年 1 月发布,Web API OData 于 2013 年 1 月发布,所以我认为“我需要 ODataController 来获得完整的 ODataSupport”以匹配 OData 规范是正确的。 【参考方案1】:这很好地解释了这些差异: http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx
【讨论】:
【参考方案2】:谁能解释我什么时候应该继承我的控制器表单 ODataController 与 ApiController?
如果您想公开一个遵循OData protocol 的端点,您可能想从ODataController
继承。如果您想做其他事情,例如 REST 端点,请从 ApiController
继承。
应用 WebAPI OData 框架的某些部分而不应用其他部分可能不是一个好主意。在某些情况下它可能会起作用,但在其他情况下可能效果不佳。例如,您可能会获得查询支持,但可能不会生成 $metadata 端点(这只是推测,实际症状可能不同)。
听起来您已经在使用 EntityFramework。我知道有许多示例展示了如何将其公开为 OData 端点。
如果您出于某种原因不想这样做,您可以自己实现查询。这在this tutorial 的几个地方有简要介绍,但要点是在您的操作中添加ODataQueryOptions<T>
类型的参数,并使用其上的方法来过滤您的结果集。但是,为所有可能的 OData 查询生成良好的数据库查询可能会很痛苦,因此您应该尽可能避免这种情况。
【讨论】:
谢谢。我改变了我的问题的措辞。希望它变得更加清晰。 我认为如果您将控制器分开放在自己的目录中可能是个好主意。就像在 Controllers 文件夹中创建一个 API 文件夹和一个 OData 文件夹一样。使用 OData 的一个优点是您不必为每个请求的项目创建新的硬编码 linq 查询;它对于查询单个实体(未连接的实体)非常有用。查询 url 会自动为您生成 linq 表达式。通过消除添加新 linq 查询的需要,您可以避免代码维护和项目开销。 我会使用 APIController 处理复杂的联合实体关系,使用 OData 处理简单的单一实体关系。以上是关于公开 DTO 时的 ApiController 与 ODataController的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC 4 中 Controller 与 ApiController 做读取新增更新删除 ( CRUD )