ApiController vs ODataController when exposing DTOs
Solution 1
Can someone explain me when I should inherit my controller form ODataController vs ApiController?
You would want to inherit from ODataController
if you want to expose an endpoint that adheres to the OData protocol. If you want to do something else, such as a REST endpoint, then inherit from ApiController
.
Applying some parts of the WebAPI OData framework but not others is probably not a good idea. It may in some cases, but will probably not work well in others. For example you may get querying support, but the $metadata endpoint may not be generated (that's just speculation, the actual symptoms may be different).
It sounds like you're using EntityFramework already. I know there are a number of samples showing how to expose that as an OData endpoint.
If you don't want to do that for some reason, you can implement querying yourself. This is briefly covered in a few places on this tutorial, but the gist is to add a parameter of type ODataQueryOptions<T>
to your action, and use the methods on it to filter your result set. However, it can be painful to generate good database queries for all possible OData queries, so you should avoid that if possible.
Solution 2
This explains the differences nicely: http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx
Related videos on Youtube
![Pavel Voronin](https://i.stack.imgur.com/BYYrP.jpg?s=256&g=1)
Pavel Voronin
Nice videos worth watching: What were they thinking? Language design choices that seem wrong, until they don’t - Bill Wagner Seven Ineffective Coding Habits of Many Programmers - Kevlin Henney Code that fits your brain - Adam Tornhill Clean Code: A Reader-Centered Approach - Matthew Renze SOLID Deconstruction - Kevlin Henney Self-documenting Code: A Mob Powered Vocabulary Lesson - Cory House DDD, F# and Types
Updated on October 23, 2020Comments
-
Pavel Voronin over 3 years
Can someone explain me when I should inherit my controller form
ODataController
vsApiController
?The question is caused by the fact that results returned by
ApiController
can be filtered with OData query.If I apply
QueraybleAttribute
to contoller's methods, query is processed even if action returnsIEnumerable
.
However without this attribute but with the callconfig.EnableQuerySupport()
, query is processed only if method returnsIQueryable
.
I think it is not consistent behavior. WebAPI documentation and examples imply that controller must inerit from ODataController. And I'm a little confused.
EitherApiController
accidentally
and partially supports part (at least $skip, $filter and $top) of OData protocol. Or this is by design and I need ODataController for complete ODataSupport.The real problems is that my service exposes DTOs, not POCOs. There may be no one to one mappings. There's need to convert OData query againts DTOs to EF query against POCOs.
Now just playing with OData. I retrieve entities and convert them to DTOs. Admittedly, this is not very performant to get all of them from DB for each request yet tolerale for experiments. But there's definetely no need to return all entities to the client if it requires some filtered subset of DTOs.
OData query started working out of the box with ApiController and Querayble attribute, but the aforementioned inconsistency makes me thing I doing something wrong.-
Michael over 10 yearsI think it's because it implements additional functionality like metadata allowing WCF Data Services client to be used: 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 (with query support) came out Jan 2012 and Web API OData in Jan 2013 so I think you're right with "I need ODataController for complete ODataSupport" to match OData spec.
-
-
Pavel Voronin almost 11 yearsThanks. I changed the wording of my question. Hope it became more clear.
-
sksallaj over 10 yearsI think it may be a good idea if you separate your controllers in their own directory. Like make an API folder and an OData folder in your Controllers folder. One advantage of using OData is that you don't have to create a new hardcoded linq query for each requested item; it's very useful for querying a single entity (not joined entities). The querying url auto generates the linq expression for you. By eliminating the need of adding new linq queries, you avoid code maintenance and overhead for your project.
-
sksallaj over 10 yearsI'd use APIController for complex joined entity relationships, and OData for simple single entity relationships.