0
votes

When I set the datasource to WebAPI binding, the HTTP GET is being invoked on the controller and it returns the correct data. The problem is that my Kendo Grid is not binding the data correctly, instead I get an empty grid as a result.

@(Html.Kendo().Grid(Model)
        .Name("Accounts")
        .Columns(columns =>
        {
          columns.Bound(c => c.Description).Title("Account Name");
          columns.ForeignKey(c => c.Type, (System.Collections.IEnumerable)ViewData["accountTypes"], "Id", "Name").Title("Account Type");
          columns.ForeignKey(c => c.Currency, (System.Collections.IEnumerable)ViewData["currencyTypes"], "Id", "Name").Title("Account Currency");
          columns.Command(command => { command.Edit(); command.Destroy(); }).Width(210);
        })
        .Sortable(sortable =>
        {
          sortable.SortMode(GridSortMode.SingleColumn);
          sortable.AllowUnsort(false);
        })
        .Pageable(pageable => pageable
            .Refresh(true)
            .PageSizes(true)
            .ButtonCount(5)
        )
        .ToolBar(toolbar => { toolbar.Create(); })
        .Editable(editable => editable.Mode(GridEditMode.InLine))
        .DataSource(dataSource => dataSource
          .WebApi()
          .Model(model =>
          {
            model.Id(p => p.Id);
            model.Field(p => p.Currency).DefaultValue(0).Editable(true);
            model.Field(p => p.Description).Editable(true);
            model.Field(p => p.Type).Editable(true);
          })
          .ServerOperation(true)
          .Read(read => read.Action("Get", "Accounts"))
          .Create(create => create.Action("Post", "Accounts"))
          .Update(update => update.Action("Put", "Accounts", new { id = "{0}" }))
          .Destroy(destroy => destroy.Action("Delete", "Accounts", new { id = "{0}" }))
        .PageSize(10)
    )
)

Controller

// GET: api/values
        [HttpGet]
        public DataSourceResult Get([DataSourceRequest]DataSourceRequest request)
        {
            return _context.Accounts.ToDataSourceResult(request);
        }

I always get an HTTP 200 OK as a result of the paging or sorting command, but the grid is empty afterwards. The URL generated by Kendo is:

http://localhost:58829/Accounts/Get?sort=&page=1&pageSize=10&group=&filter=

Which actually returns JSON when I open it with a browser.

2
Have you tried converting the data being returned with Json()? i.e. return Json(_context.Accounts.ToDataSourceResult(request)); and change your controller function to public ActionResult Get([DataSourceRequest]DataSourceRequest request).. - Sandman
@Sandman, It's giving the same results - JF Beaulieu
What if, along with the above change to your controller, modify your grid DataSource as follows. Replace WebApi() with Ajax() and set .ServerOperation(false). If this still doesn't fix it, consider updating your question with the structure of the data being returned from your controller method. - Sandman

2 Answers

1
votes

The problem seems to be that you are mixing two different ways to load the data. On the one hand you are passing the Model by param to the grid (this approach is used when ServerOperation = false) and on the other hand you are setting ServerOperation = true and specifying a read action.

The reason why the grid is empty in this case is probably because either the Model is empty.

Take a look at this demo example for a reference on how to implement the remote source databinding: http://demos.telerik.com/aspnet-core/grid/remote-data-binding

Example View:enter image description here

Example controller: enter image description here

Hope this helps KendoGrid is an awesome library but like many other libraries it could definitely use better exception handling and more user friendly exceptions :) In my opinion the grid should have shown an exception in this case.

0
votes

The problem was this: when declaring the Kendo Grid and passing the Model as a parameter like so:

@(Html.Kendo().Grid(Model)

You need to remove the .Read() action, and make sure to use .ServerOperation(false). This works either with WebApi binding or Ajax binding:

.DataSource(dataSource => dataSource
      .WebApi()    // also works with .Ajax()
        .Model(model =>
        {
          model.Id(p => p.Id);
        }
      )
      .ServerOperation(false)
      .Create(create => create.Action("Post", "Invoices"))
      .Update(update => update.Action("Put", "Invoices", new { id = "{0}" }))
      .Destroy(destroy => destroy.Action("Delete", "Invoices", new { id = "{0}" }))
      .PageSize(10)
)

Also, the DataSourceResult Get() method can be removed.