Kendo Grid自定义编辑器绑定导致maxJsonLength错误

Kendo Grid自定义编辑器绑定导致maxJsonLength错误

问题描述:

我有一个Kendo网格,它具有绑定到相关表的列。网格显示了一个固定的4级层次结构:PK_Field,Name,Level_1,Level_2,Level_3和Level_4。
我绑定使用this examble from Telerik水平列:Kendo Grid自定义编辑器绑定导致maxJsonLength错误

剑道格:

@(Html.Kendo().Grid<MyViewModel>() 
    .Name("Grid") 
    .Columns(columns => 
    { 
     columns.Command(command => 
     { 
      command.Edit(); 
      command.Destroy();   
     }).Width(220); 
     columns.Bound(t => t.Name).Width(80); 
     columns.Bound(t => t.CreateDate).Width(80); 
     columns.ForeignKey(t => t.Level1Id, (System.Collections.IEnumerable)ViewData["Level1"], "Id", "Text").Title("Level 1").EditorTemplateName("EditLevel1Id"); 
     columns.ForeignKey(t => t.Level2Id, (System.Collections.IEnumerable)ViewData["Level2"], "Id", "Text").Title("Level 2").EditorTemplateName("EditLevel2Id"); 
     columns.ForeignKey(t => t.Level3Id, (System.Collections.IEnumerable)ViewData["Level3"], "Id", "Text").Title("Level 3").EditorTemplateName("EditLevel3Id"); 
     columns.ForeignKey(t => t.Level4Id, (System.Collections.IEnumerable)ViewData["Level4"], "Id", "Text").Title("Level 4").EditorTemplateName("EditLevel4Id"); 
     columns.Bound(t => t.Username).Width(100); 
    }) 

服务器端:

private void PopulateCategories() 
    { 
     var dataContext = new SampleEntities(); 
     var categories = dataContext.Categories 
        .Select(c => new CategoryViewModel { 
         CategoryID = c.CategoryID, 
         CategoryName = c.CategoryName 
        }) 
        .OrderBy(e => e.CategoryName); 

     ViewData["Level1"] = categories;  
    } 

列LEVEL_1到Level_4每个人都有自己ViewData变量。

当用于Level_4的数据量变大时,出现“字符串的长度超过maxJsonLength属性中设置的值”错误。

我所有的服务器端方法都设置为使用MaxJsonLength = Int32.MaxValue,但ViewData变量不受此影响,因此当它们变得太大时会导致错误。

如何防止大ViewData变量产生错误?

编辑

编辑模板 -
等级1:

@using Kendo.Mvc.UI 

@(Html.Kendo().DropDownListFor(m => m) 
     .AutoBind(false) 
     .OptionLabel("Select a value...") 
     .DataTextField("Text") 
     .DataValueField("Id") 
     .DataSource(dataSource => 
     { 
      dataSource.Read(read => read.Action("GetLevel1Descriptions", "MyAdmin").Data("filter1Descriptions")) 
      .ServerFiltering(true); 
     }) 
     .HtmlAttributes(new { id = "Level1Id" }) 
) 
@Html.ValidationMessageFor(m => m) 

等级2:

@using Kendo.Mvc.UI 

@(Html.Kendo().DropDownListFor(m => m) 
     .AutoBind(false) 
     .OptionLabel("Select a value...") 
     .DataTextField("Text") 
     .DataValueField("Id") 
     .DataSource(dataSource => 
     { 
      dataSource.Read(read => read.Action("GetLevel2Descriptions", "Admin").Data("filterLevel2Descriptions")) 
      .ServerFiltering(true); 
     }) 
     .CascadeFrom("Level1Id") 
     .HtmlAttributes(new { id = "Level2Id" }) 
) 
@Html.ValidationMessageFor(m => m) 

3级别和级别4遵循Level2的模式

这里AR EA夫妇的事情我做,以解决maxJson长度被击中的问题:

1)的Web.config变化:

<system.web> 
    <httpRuntime targetFramework="4.5" maxRequestLength="50000000" /> 
    all other settings remove for Brevity..... 
</system.web> 


<system.webServer> 
    <security> 
     <requestFiltering> 
     <requestLimits maxAllowedContentLength="2147483648" /> 

     </requestFiltering> 
    </security> 
    all other settings remove for Brevity..... 
</system.webServer> 


<system.web.extensions> 
    <scripting> 
     <webServices> 
     <jsonSerialization maxJsonLength="50000000" recursionLimit="500"> 
      <converters></converters> 
     </jsonSerialization> 
     </webServices> 
    </scripting> 
    </system.web.extensions> 

2)返回使用这三种变化的JsonResult对象的自定义版本:

protected virtual JsonResult GetLargeJson<T>(List<T> model, DataSourceRequest request = null, bool denyGet = true) 
{ 
    JsonResult result = null; 
    if (request == null) 
    { 
     result = Json(model); 
    } 
    else 
    { 
     result = Json(model.ToDataSourceResult(request, ModelState)); 
    } 


    result.MaxJsonLength = Int32.MaxValue; 
    result.JsonRequestBehavior = (denyGet) ? JsonRequestBehavior.DenyGet : JsonRequestBehavior.AllowGet; 
    return result; 
} 

protected virtual JsonResult GetLargeJson(DataTable model, DataSourceRequest request = null, bool denyGet = true) 
{ 
    JsonResult result = null; 
    if (request == null) 
    { 
     result = Json(model); 
    } 
    else 
    { 
     if (!ModelState.IsValid) 
     { 
      DataSourceResult response = model.ToDataSourceResult(request); 
      response.Errors = ModelState.SerializeErrors(); 


      result = Json(response); 

     } 
     else 
     { 
      result = Json(model.ToDataSourceResult(request)); 
     } 
    } 

    result.MaxJsonLength = Int32.MaxValue; 
    result.JsonRequestBehavior = (denyGet) ? JsonRequestBehavior.DenyGet : JsonRequestBehavior.AllowGet; 


    return result; 


} 



protected virtual JsonResult GetLargeJson<T>(T model, DataSourceRequest request = null, bool denyGet = true) 
{ 
    JsonResult result = null; 
    if (request == null) 
    { 
     result = Json(model); 
    } 
    else 
    { 
     result = Json(new[] { model }.ToDataSourceResult(request, ModelState)); 
    } 

    result.MaxJsonLength = Int32.MaxValue; 
    result.JsonRequestBehavior = (denyGet) ? JsonRequestBehavior.DenyGet : JsonRequestBehavior.AllowGet; 


    return result; 


} 

其中type T是通用的。这样我就有了处理大型对象的标准方式,并确保它们不会炸掉一个错误。

我会建议也许看看处理自定义编辑的替代方式,而不是引导ViewData对象中的所有内容,因为这会变得异常大,因为您正在经历和如果数据用于下拉/多选类型控件,然后使用ajax版本的控件可能会导致长期更好的性能。如果您可以提供更多关于您正在使用的编辑模板的详细信息,我很乐意提供帮助,提供执行此类操作的清洁方法。

+0

@David_Shorthose:感谢您的反馈。我也实现了JsonResult重载和web.config设置,但ViewData对象不受这些更改的影响。 – callisto

+0

所以调试代码什么是实际返回/存储在viewdata?你确定它只是抛出这个错误的级别4列表?例如这不是另一个请求被误解链中的错误。 –

+0

我可以确认它是level4对象(包含约30k条目的id和文本对列表)。如果我减少Level4对象中的项目数量,则不会发生错误。 – callisto