Returning total count when not using a LINQ provider

Topics: ASP.NET Web API
Apr 5, 2013 at 8:45 PM
I have a controller inheriting from EntitySetController, but needs to get its data from a legacy class library that does not have a LINQ provider. I have it returning data, but the total number of records needs to come back in "odata.count". I tried setting the total using "this.Request.SetInlineCount(orders.TotalRecords);", but that never makes it back to the client. Am I misunderstanding the purpose of SetInlineCount, or am I going about this wrong? Thanks!

Querystring: ?%24inlinecount=allpages&%24top=3
Response returns "3" for the "odata.count", and 3 records in the "value", even though there are 4 total records.
        public override IQueryable<DemoSalesOrder> Get()
        {
            ODataQueryOptions<DemoSalesOrder> queryOptions = this.QueryOptions;

            CSalesOrders orders = new CSalesOrders();
            // Omitted - Set paging parameters here, using options in this.QueryOptions.
            orders.Load();

            this.Request.SetInlineCount(orders.TotalRecords);

            // Note: MapToModel just maps the internal business class to my external model exposed through WebAPI.
            IQueryable<DemoSalesOrder> result = MapToModel(orders.Values.Cast<CSalesOrder>().ToList()).AsQueryable<DemoSalesOrder>();

            return result;
        }
Apr 5, 2013 at 9:23 PM
Aaah. Looks like a bug. We are overwriting the inline count that you have set in your action in our QueryableAttribute action filter which runs after your action got executed. I am assuming you have enabled Query composition using config.EnableQuerySupport().
Apr 8, 2013 at 1:11 PM
Yes, I am using config.EnableQuerySupport, so that must be it. In our app, we will have to support this older BO layer, as well as also be able to call some internal WCF services as well, and would like to expose them as OData queryable methods in our WebAPI. Do you have a recommendation for a workaround? Do I also need to add this in as an issue on the Issues tab in this site? Thanks!
Apr 8, 2013 at 6:04 PM
Please open an issue here https://aspnetwebstack.codeplex.com/WorkItem/Create.

And regarding a temporary workaround, you can do something like this,
public class InlineCountRetainingQueryable : QueryableAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        // backup inlinecount.
        long? inlineCount = actionExecutedContext.Request.GetInlineCount();

        base.OnActionExecuted(actionExecutedContext);

        if (inlineCount.HasValue)
        {
            // overwrite with the backed up value.
            actionExecutedContext.Request.SetInlineCount(inlineCount.Value);
        }
    }
}
and call this to register it instead of config.EnableQuerySupport()
config.EnableQuerySupport(new InlineCountRetainingQueryable());
Another workaround I could think of is to write a message handler that removes $inlinecount query option from the request uri if it is present.
Apr 9, 2013 at 1:51 PM
Thanks, I will try your suggestion. I added it as an issue: https://aspnetwebstack.codeplex.com/workitem/976