jsonasp.net-mvcasp.net-web-api2model-bindingjquery-bootgrid

jQuery Bootgrid - Ajax Sort Parameter with ASP.NET MVC Actions


I managed to create an ApiController retrieving data from my repositories, and populating a grid in my view through Bootgrid with Ajax. This is an example of request data sent to Api's Action, given by their Docs here (look for POST Body Request tab):

current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed

Here is an example URL:

http://localhost/api/SomeController?current=1&rowCount=10&sort%5BName%5D=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed

I created two Helper classes to handle data I must return as response, and sort data (as it's an array):

public class SortData
{
    public string Field { get; set; } // FIeld Name
    public string Type { get; set; } // ASC or DESC
}

public class BootgridResponseData<T> where T: class
{
    public int current { get; set; } // current page
    public int rowCount { get; set; } // rows per page
    public IEnumerable<T> rows { get; set; } // items
    public int total { get; set; } // total rows for whole query
}

Therefore, my action is as follow:

    public BootgridResponseData<SomeViewModel> Get(int current, int rowCount, List<SortData> sort, string searchPhrase, string id)
    {
       // get items and return a bootgrid response data with them...
    }

The method is invoked and all parameters come with data properly, except sort, which is always null.

What kind of parameter should I expect for this? I also tried to put object but it comes null anyway.


Solution

  • After learning a bit more, I saw Bootgrid has a requestHandler setting which allows you to manipulate data sent to server.

    I did it in my javascript like this:

    var grid = $("#my-grid").bootgrid({
            ajax: true,
            rowCount: 10,
            ajaxSettings: {
                method: "POST",
                cache: true
            },
            requestHandler: function (request) {
                // Scan the original sort object from Bootgrid...
                // and populate an array of "SortData"...
                request.sortItems = [];
                if (request.sort == null)
                    return request;
                for (var property in request.sort) {
                    if (request.sort.hasOwnProperty(property)) {
                        request.sortItems.push({ Field: property, Type: request.sort[property] });
                    }
                }
                return request;
            },
            url: "/api/FooApi"
        });
    

    Then I created my post action in API like this:

    public class FooApiController : ApiController
    {
    
        [HttpPost]
        public BootgridResponseData<FooModel> Get(BootgridRequestData model)
        {
            // This would come from some data store, using the request params...
            // I use PagedList to make pagination easier...
            IPagedList<FooModel> itemsPaged = store.GetPagedFoo();
    
            // Then return the response with data...
            return new BootgridResponseData<FooModel>()
            {
                current = model.current,
                rowCount = model.rowCount,
                rows = itemsPaged,
                total = itemsPaged.TotalItemCount
            };
        }
    }
    

    The BootgridResponseData has already been shown in my question. I just added a BootgridRequestData which the following structure:

    public class BootgridRequestData
    {
        public int current { get; set; }
        public int rowCount { get; set; }
        public string searchPhrase { get; set; }
        public IEnumerable<SortData> sortItems { get; set; }
    }
    

    Then I could even use my original SortData helper class:

    public class SortData
    {
        public string Field { get; set; } // FIeld Name
        public string Type { get; set; } // ASC or DESC
    }