locked
How to use ODataQueryOptions in case of TypeLess (UnTyped) object in ASP.NET WebApi / OData project RRS feed

  • Question

  • User375312560 posted

    I have been referring Asp.net WebApi 2.2 support for OData. It is very interesting where WebApi handles lot of OData V4 protocol related things.

    I need to implement an Odata service where I dont have CLR object. I get to know about properties of my class at runtime. Its like I have xml files which store Sql queries. I read those xml files and execute the queries in them. After reading the XML file I realize the columns and would like expose this information under OData service.

    Challenge I have been facing is that I am not able to apply ODataQueryOptions on untyped (non CLR) objects.

    Sample codehttps://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataUntypedSample/ReadMe.txt shows how to expose untyped object from WebApi OData service but it does not show how to apply ODataQueryOptions.

    public class ProductsController : ODataController
      {
        private static IQueryable<IEdmEntityObject> Products = Enumerable.Range(0, 20).Select(i =>
        {
          IEdmEntityType productType = (IEdmEntityType)ODataUntypedModel.Model.FindType("AnalyticsPortal.Product");
    
          EdmEntityObject product = new EdmEntityObject(productType);
          product.TrySetPropertyValue("Id", i);
          product.TrySetPropertyValue("Name", "Product " + i);
          product.TrySetPropertyValue("Price", i + 0.01);
          product.TrySetPropertyValue("Category", "Category - " + i);
    
          return product;
        }).AsQueryable();
    
        ///*
        public EdmEntityObjectCollection Get()
        {
    
    
          //return productsContext.Products.AsQueryable();
    
          var path = Request.ODataProperties().Path;
          var edmType = path.EdmType;
          var collectionType = edmType as IEdmCollectionType;
          var entityType = collectionType.ElementType.Definition as IEdmEntityType;
          var model = Request.ODataProperties().Model;
          var queryContext = new ODataQueryContext(model, entityType, path);
          var queryOptions = new ODataQueryOptions(queryContext, Request);
    
    
    
          //Apply the query option on the IQueryable here.
          //queryOptions
          //How ??
          //queryOptions.ApplyTo() work only on CLR types
    
          //IQueryable<IEdmEntityObject>
    
          return new EdmEntityObjectCollection(new EdmCollectionTypeReference(collectionType), Products.ToList());
        }
        //*/
      }

    I would appreciate if someone can point me to a way where some framework or plugin can handle OData query options (filter, select, order etc...)

    Tuesday, July 7, 2015 4:06 PM

All replies

  • User438962230 posted

    Hi ojasmaru,

    Please try to build the query options with the ODataQueryContext, see this sample code:

        var collectionType = Request.GetODataPath().EdmType as IEdmCollectionType;
        var entityType = collectionType.ElementType.AsEntity();
        var entitySetName = entityType.EntityDefinition().Name;
        var queryContext = new ODataQueryContext(Request.GetEdmModel(), entityType.Definition);
        var queryOptions = new ODataQueryOptions(queryContext, Request);

    For more information, take a look at this blogpost which is about typeless entity support:

    Typeless Entity Object Support in WebApi

    Wednesday, July 8, 2015 12:05 PM
  • User375312560 posted

    Hi Caillen,

    Thanks for you response. I have been through the blog you mentioned. You can already find my question in comment of that blog.

    My real question is - Challenge I have been facing is that I am not able to apply ODataQueryOptions on untyped (non CLR) object. I dont see it being answered in the code that you extracted from the blog.

    Wednesday, July 8, 2015 5:05 PM
  • User438962230 posted

    Sorry ojasmaru, I'm not quite sure if we can do it and how to do it. I'll involve some other engineers into your case. But this will take some time, so please patient. If there're any updates, we'll come back. 

    Thanks for your understanding.

    Thursday, July 9, 2015 11:00 AM
  • User375312560 posted

    Hi Caillen,

    Thanks for your response. I would appreciate if you can get some help in this matter. I would be waiting for any update.

    Thursday, July 9, 2015 4:34 PM
  • User1104055534 posted

    Hi ojasmaru,

    Thanks for your post. I did some research based on your description but no luck to find much information as well. As you know, ApplyTo does not apply to untyped ODataQueryOptions as there is no CLR type involved and IQueryable<T> requires a CLR type.

    Hope this blog post could help you somewhat- http://blogs.msdn.com/b/webdev/archive/2013/02/25/translating-odata-queries-to-hql.aspx. It decribes how to expose a non-IQueryable data source to be queried using the OData query syntax using AspNet Web API OData. It also provide sample code link.

    This thread discribed something else https://social.msdn.microsoft.com/Forums/en-US/99d678cf-0fba-47ba-b936-74849975a508/query-options-filter-and-orderby-not-working-with-untyped-properties?forum=adodotnetdataservices.

    Hope the information useful to you.

    Best Regards

    Monday, July 13, 2015 1:25 AM
  • User375312560 posted

    Hi gtscdsi,

    Thanks for your response. I infer from your response that there is no way in WebApi to use ODataQuestionOption out of the box for untyped objects. It looks like I would have write all the logic to filter, sort, order etc... data based on query options. I was trying to avoid writing all that as it would cost time and maintaining code to future OData versions and features would be challenging task. I was really excited looking at offering from WebApi to support OData but I guess its not useful in this case.

    I did look at the blog reference and it does give some starting pointers but I am not sure if that the route to go.

    I tried using creating a CLR class derived from ICustomTypeDescriptor & implemented GetProperties to return my dynamic properties but seems like OData classes in WebApi dont seems to call GetProperties on ICustomTypeDescriptor. This would have been perfect workaround but proved to be not useful.

    Please do update this thread if you here any more on this topic. Once again thanks...

    Monday, July 13, 2015 1:23 PM