Reconstructing an ODataQueryOptions and GetInlineCount Returning Zero

In the odata webapi call that PageResult returns, I extract the requestUri from the method parameter, process the filter terms, and then create a new ODataQueryOptions object using the new uri.

(The PageResult methodology is based on this post: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options )

Here is the original incoming uri that includes% 24inlinecount = allpages

http://localhost:59459/api/apiOrders/?%24filter=OrderStatusName+eq+'Started'&filterLogic=AND&%24skip=0&%24top=10&%24inlinecount=allpages&_=1376341370337 

Everything works fine in terms of the returned data, except for Request.GetInLineCount returns null.

This kills paging on the client side, since the client ui elements do not know the total number of records.

There must be something wrong with the way I create the new ODataQueryOptions object.

See my code below. Any help would be greatly appreciated.

I suspect that this post may contain some hints https://stackoverflow.com/a/167189/2129 , but I'm at a dead end.

 public PageResult<OrderVm> Get(ODataQueryOptions<OrderVm> options) { var incomingUri = options.Request.RequestUri.AbsoluteUri; //manipulate the uri here to suit the entity model //(related to a transformation needed for enumerable type OrderStatusId ) //eg the query string may include %24filter=OrderStatusName+eq+'Started' //I manipulate this to %24filter=OrderStatusId+eq+'Started' ODataQueryOptions<OrderVm> options2; var newUri = incomingUri; //pretend it was manipulated as above //Reconstruct the ODataQueryOptions with the modified Uri var request = new HttpRequestMessage(HttpMethod.Get, newUri); //construct a new options object using the new request object options2 = new ODataQueryOptions<OrderVm>(options.Context, request); //Extract a queryable from the repository. contents is an IQueryable<Order> var contents = _unitOfWork.OrderRepository.Get(null, o => o.OrderByDescending(c => c.OrderId), ""); //project it onto the view model to be used in a grid for display purposes //the following projections etc work fine and do not interfere with GetInlineCount if //I avoid the step of constructing and using a new options object var ds = contents.Select(o => new OrderVm { OrderId = o.OrderId, OrderCode = o.OrderCode, CustomerId = o.CustomerId, AmountCharged = o.AmountCharged, CustomerName = o.Customer.FirstName + " " + o.Customer.LastName, Donation = o.Donation, OrderDate = o.OrderDate, OrderStatusId = o.StatusId, OrderStatusName = "" }); //note the use of 'options2' here replacing the original 'options' var settings = new ODataQuerySettings() { PageSize = options2.Top != null ? options2.Top.Value : 5 }; //apply the odata transformation //note the use of 'options2' here replacing the original 'options' IQueryable results = options2.ApplyTo(ds, settings); //Update the field containing the string representation of the enum foreach (OrderVm row in results) { row.OrderStatusName = row.OrderStatusId.ToString(); } //get the total number of records in the result set //THIS RETURNS NULL WHEN USING the 'options2' object - THIS IS MY PROBLEM var count = Request.GetInlineCount(); //create the PageResult object var pr = new PageResult<OrderVm>( results as IEnumerable<OrderVm>, Request.GetNextPageLink(), count ); return pr; } 

EDIT
Therefore, the corrected code should read

 //create the PageResult object var pr = new PageResult<OrderVm>( results as IEnumerable<OrderVm>, request.GetNextPageLink(), request.GetInlineCount(); ); return pr; 

EDIT
Avoids the need to convert an enum string in a controller method by applying a Json transform to the OrderStatusId property (enumeration) of the OrderVm class

 [JsonConverter(typeof(StringEnumConverter))] public OrderStatus OrderStatusId { get; set; } 

This eliminates the foreach loop.

+2
source share
1 answer

InlineCount will be present only when the client requests it through the $ inlinecount option.

In your uri change logic, add the query parameter $inlinecount=allpages if it is not already present.

In addition, there is a small error in your code. The new ODataQueryOptions you create uses the new request , where, as in the GetInlineCount call, you use the old request . They do not match.

Must be

 var count = request.GetInlineCount(); // use the new request that your created, as that is what you applied the query to. 
0
source

Source: https://habr.com/ru/post/1235397/


All Articles