【问题标题】:Kendo Grid CustomEditor binding causes maxJsonLength errorKendo Grid CustomEditor 绑定导致 maxJsonLength 错误
【发布时间】:2015-11-02 19:46:46
【问题描述】:

我有一个将列绑定到相关表的 Kendo Grid。网格显示了一个固定的 4 级层次结构,该层次结构被展平:PK_Field、Name、Level_1、Level_2、Level_3 和 Level_4。
我使用this examble from Telerik 绑定级别列:

剑道网格:

 @(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)

Level3 和 Level4 遵循 Level2 模式

【问题讨论】:

    标签: c# asp.net asp.net-mvc telerik


    【解决方案1】:

    为了解决 maxJson Length 被击中的问题,我做了几件事:

    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 版本的控件可能会带来更好的性能。如果您可以提供有关您正在使用的编辑模板的更多详细信息,我很乐意帮助您建议一种执行此类操作的清洁方式。

    【讨论】:

    • @David_Shorthose:感谢您迄今为止的反馈。我也实现了 JsonResult 重载和 web.config 设置,但 ViewData 对象不受这些更改的影响。
    • 那么调试代码实际上返回/存储在视图数据中的是什么?您确定只是抛出此错误的 4 级列表吗?例如这不是错误链中的另一个请求。
    • 我可以确认它是 level4 对象(包含大约 30k 个条目的 id 和文本对列表)。如果我减少 Level4 对象中的项目数量,则不会发生错误。
    • 我会认真重新考虑将这些加载到视图数据中,因为 30K 的数据必须花费大量时间来渲染。此外,我在此阶段基于模板假设选项不可为空?我可能会建议远离外键绑定并使用普通的 Bound 字段,这样您就不必将值列表加载到下拉列表中。如果您愿意,我很乐意将其移至聊天中。
    • 谢谢。我确实通过 [Column.Bound] 绑定并更改网格使用的非常复杂的视图模型来实现它。我会接受您的回答,因为您的 cmets 提供了解决方案!
    猜你喜欢
    • 1970-01-01
    • 2015-05-13
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 2015-05-10
    • 2013-07-30
    • 1970-01-01
    相关资源
    最近更新 更多