0
votes

I have a Web API "ApiController" that I would like to get Kendo to do server side paging.
This is not MVC this is Web API v2.
The controller is returning json data to the caller.
The kendo grid works fine when serverPaging: = false.
The kendo grid does work when the serverPaging: = true but it does not show the correct total number of items and it does not have the correct number of pages displayed at the bottom of the grid.
I used this as the example http://bitoftech.net/2013/11/25/implement-resources-pagination-asp-net-web-api/ but the Get method with the page / page size parameters never gets called.
The Get method without parameters does get called but the request url looks like the following. localhost:9000/api/products/?{"take":2,"skip":0,"page":1,"pageSize":2}
My best guess is that the response needs something to tell the grid the number of records left but I can't find any good examples on how to tell the grid the total number of records.
I did add "X-Pagination" to the header with the total count and total pages but I don't think the kendo grid is using the information.

P.S. I know that Telerik has code for paging with Web API but I can't afford / too cheap for the new Kendo so I'm using the open source kendo.


EDIT: 4-11-14
So I finally got my original problem solved where the total number of items was not showing. While still using WEB API 2 and JSON. "NOT ODATA! I'm still working on the ODATA test but that is for another post ;)".
basically in my GET method in the controller I had to return the following:

return new
{
    TotalCount = totalCount,
    TotalPages = totalPages,
    Results = results
};

This is based on the example posted above. But in the kendo datasource schema I added the following:

schema: {
    data: function (data) {
        return data.Results || data;
    },
    total: function (data) {
        if (data.TotalCount) {
            return data.TotalCount;
        }
        return result.PageSize || result.length || 0;
     },

I never did get the Get(int page = 0, int pageSize = 10) from the example to work but I was able to parse the query string to pull out the "skip" and "take" for paging to work.

1

1 Answers

4
votes

In order to get the total records to come down correctly, you have to pass an addition query $inlinecount=allpages. I found useful information at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options. Specifically, I used the solution where the Get method in your controller looks something like:

public PageResult<Product> Get(ODataQueryOptions<Product> options)
{
    IQueryable results = options.ApplyTo(_products.AsQueryable());

    return new PageResult<Product>(
        results as IEnumerable<Product>, 
        Request.GetNextPageLink(), 
        Request.GetInlineCount());
}

That makes the result look something like:

{
  "Items": [
    { "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
    { "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },

    // Others not shown

  ],
  "NextPageLink": "http://localhost/api/values?$inlinecount=allpages&$skip=10",
  "Count": 50
}

There are a couple things you then need to do in your kendo datasource.

var source = new kendo.data.DataSource({
    type: "odata",
    schema: {
        data: function (data) {
            if (data.Items) {
                return data.Items;
            }

            return [data];
        },
        total: function (data) {
            return data.Count;
        }
    }});

I removed a lot of configuration options for brevity, but hopefully that pulls enough details together to be helpful.