Tim
Tim

Reputation: 3038

Returning OData count for non-entity set collections

I have an action routed that returns a non-entity collection.

ActionConfiguration previewInvoices = this.EntityType.Collection.Action("PreviewInvoices");
previewInvoices.ReturnsCollection<InvoicePreviewComponent>();

Now when I query to get the results, I am using a $take=20 to control paging through javascript. However it doesn't return a count as it does with entity sets with $inlinecount=allpages.

One solution I had been doing was to change the lines to:

ActionConfiguration previewInvoices = this.EntityType.Collection.Action("PreviewInvoices");
previewInvoices.ReturnsCollectionFromCollection<InvoicePreviewComponent>("InvoicePreviewComponent");

However this generates ghost entity sets in the $metadata, which I am using to generate the javascript models and requests. Not ideal, and ultimately not correct to annotate this as an entity set.

How can I modify the response JSON formatter to give the count as requested?

Upvotes: 1

Views: 1508

Answers (2)

Vikrant Verma
Vikrant Verma

Reputation: 71

This can also be achieved by an action filter:

/// <summary>
/// Use this attribute whenever total number of records needs to be returned in the response in order to perform paging related operations at client side.
/// </summary>
public class PagedResultAttribute: ActionFilterAttribute
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="actionExecutedContext"></param>
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
        if (actionExecutedContext.Response != null&& actionExecutedContext.Response.StatusCode==System.Net.HttpStatusCode.OK)
        {                
            dynamic responseContent=null;
            if (actionExecutedContext.Response.Content != null)
                responseContent = actionExecutedContext.Response.Content.ReadAsAsync<dynamic>().Result;
            var count = actionExecutedContext.Response.RequestMessage.ODataProperties().TotalCount;
            var res = new PageResult<dynamic>() {TotalCount=count,Items= responseContent };

            HttpResponseMessage message = new HttpResponseMessage();
            message.StatusCode = actionExecutedContext.Response.StatusCode;

            var strMessage = new StringContent(JsonConvert.SerializeObject(res), Encoding.UTF8, "application/json");
            message.Content = strMessage;
            actionExecutedContext.Response = message;               
        }           
    }
}

And the custom PageResult class is:

public class PageResult<T>
{      
    public long? TotalCount { get; set; }
    public T Items { get; set; }
}

Usage:

[PagedResult]
[EnableQuery()]      

Upvotes: 0

Feng Zhao
Feng Zhao

Reputation: 2995

The count value of non-entity collection won't be serialized into the response body.

But you can get the count value by the following code:

response.RequestMessage.ODataProperties().TotalCount

(Note: ODataProperties() is an extension method in static class System.Web.Http.OData.Extensions.HttpRequestMessageExtensions)

Upvotes: 1

Related Questions