2

I am trying to populate a telerik grid from a table based on date selected.

I get an error message:

System.InvalidOperationException: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property

Is there any other way I can populate Telerik grids on client events?

view:

        <%= Html.Telerik().DatePicker().Min("01/01/2011")
            .Name("Date")
            .ClientEvents(e => e.OnChange("Date_onChange"))
         %>       

    <div>
    <%= Html.Telerik().Grid<DataAccess.Entity.Dto.ReportData>()
            .Name("tblGrid")
            .DataBinding(databinding => databinding.Ajax()
            .Select("MasterDataGrid", "Report"))
            .Columns(col =>
                {
                    col.Bound(f => f.ID).Title("ID Number");
                    col.Bound(f => f.Date).Title("Date");
                })
                .Filterable(filter => filter.Enabled(true))
                .Pageable(page => page.PageSize(200))
                .Sortable(sort => sort.Enabled(true))                    
    %>
    </div>

JavaScript:

function Date_onChange() {

    var link = '/Report/DataGrid';
    var Date = $("#Date").val().toString();
    $.ajax({
        type: 'POST',
        url: link,
        data: { date: Date },
        dataType: 'json',
        success: function (result) {
            $("#tblGrid").data("tGrid").dataBind(result.data);
        },
        error: function (result) {
            $("#ErrorMessage").text(result.message);
        }
    });

};

Controller:

    [HttpPost]
    [GridAction]
    public ActionResult DataGrid(DateTime date)
    {
       var model = context.GetReportData_tblData(date);
        return View(new GridModel { Data = model });
    }
user793468
  • 4,898
  • 23
  • 81
  • 126

2 Answers2

3

It looks like you are returning far too much data. There are two possible scenarios here, and it may be one or the other or both.

(1) As your page size is 200, this implies that you are expecting a lot of data, so you may be returning far too many objects. By default, the Telerik Grid will take the entire collection and do the sorting and filtering client-side. I would try implementing server-side paging and sorting so that you only return 1 page of data at a time.

View:

@(Html.Telerik.Grid<IEnumerable<MyClass>>()
  .Name("MyGrid")
  .Columns(col => // column definitions)
  .EnableCustomBinding(true)
  .Pageable(pg =>
    {
      paging.Total(Model.TotalCount);
      paging.PageSize(Model.PAGE_SIZE);
    })
  .DataBinding(db =>
    {
      db.Ajax().Select("DataGrid", "MyController");
    }
 )

Controller:

[GridAction(EnableCustomBinding = true)]
public ActionResult DataGrid(GridCommand command, DateTime date)
{
   MyModel model = new MyModel();
   IEnumerable<MyClass> data = context.GetReportData_tblData(date);

   // apply paging, filtering, grouping, and sorting
   GridModel gm = data.AsQueryable().ToGridModel(command.Page, command.PageSize, command.SortDescriptors, command.FilterDescriptors, command.GroupDescriptors);

   return View(gm);
}

Telerik provides a handy extension method to apply all the paging, sorting, filtering and grouping: IQueryable<T>.ToGridModel(), which you can find in the Telerik.Web.Mvc.Extensions assembly (h/t: vladimir77).

(2) If your DataAccess.Entity.Dto.ReportData class has a lot of properties, and/or some of its properties have long strings or child objects which are also recursively serialized, then you can easily hit the transfer limit with just a few objects. I notice you are only using two properties in the Grid. Please consider creating view model objects that only have the data that you need (that's good practice anyway).

howcheng
  • 2,211
  • 2
  • 17
  • 24
2

You can increase the default JavaScriptSerializer.MaxJsonLength. Just see this answer: https://stackoverflow.com/a/7207539/443379

After this the filtering, paging... functionality won't work anymore. All you have to do though is use CustomBinding (inspired from @howcheng's answer):

[GridAction(EnableCustomBinding=true)]
public ActionResult DataGrid(GridCommand command, DateTime date)
{
   var data = context.GetReportData_tblData(date)
     .ToGridModel(command.Page, command.PageSize, command.SortDescriptors, command.FilterDescriptors, command.GroupDescriptors);

   var serializer = new JavaScriptSerializer();
   var result = new ContentResult();
   serializer.MaxJsonLength = Int32.MaxValue; // overriding the default max length
   result.Content = serializer.Serialize(data);
   result.ContentType = "application/json";
   return result;
}

This works even for Client Operation Mode. You can refactor this to a class: http://macaalay.com/2011/09/27/large-json-result-for-teleriks-mvc-grid/

Community
  • 1
  • 1
Valentin
  • 717
  • 10
  • 21