ApiController vs ODataController when exposing DTOs

16,311

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

Share:
16,311

Related videos on Youtube

Pavel Voronin
Author by

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, 2020

Comments

  • Pavel Voronin
    Pavel Voronin over 3 years

    Can someone explain me when I should inherit my controller form ODataController vs ApiController ?

    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 returns IEnumerable.
    However without this attribute but with the call config.EnableQuerySupport(), query is processed only if method returns IQueryable.
    I think it is not consistent behavior. WebAPI documentation and examples imply that controller must inerit from ODataController. And I'm a little confused.
    Either ApiController 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.

  • Pavel Voronin
    Pavel Voronin almost 11 years
    Thanks. I changed the wording of my question. Hope it became more clear.
  • sksallaj
    sksallaj over 10 years
    I 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
    sksallaj over 10 years
    I'd use APIController for complex joined entity relationships, and OData for simple single entity relationships.