asp:GridView大数据集回发失败问题求解(非常规方案)
解决ASP.NET嵌套UpdatePanel下JSON反序列化成员数超限问题
背景
- 页面结构:
asp:GridView置于内层UpdatePanel中,内层UpdatePanel又嵌套在外层UpdatePanel内- 外层UpdatePanel属性:
UpdateMode="Conditional"、ChildrenAsTriggers="false" - 内层UpdatePanel属性:
UpdateMode="Conditional"、ChildrenAsTriggers="true"
- 外层UpdatePanel属性:
- 业务逻辑:根据Infragistics WebDataTree选中的公司,GridView加载最多3000条设施数据,同时设施名称作为选中节点的子节点加载到WebDataTree中
问题
当设施数量较多时,执行网格排序、分页或切换树节点操作,抛出异常:
Uncaught Sys.WebForms.PageRequestManagerServerErrorException: Sys.WebForms.PageRequestManagerServerErrorException: The maximum number of items has already been deserialized into a single dictionary by the JavaScriptSerializer. To change the maximum allowed JSON dictionary entry count from its current value of 10000, change the "aspnet:MaxJsonDeserializerMembers" setting.
已尝试无效方案
- 逐步调大
asp:MaxJsonDeserializerMembers至上限2147483647,同步设置maxJsonLength为相同值,无效果 - UI优化:仅保留一个树节点的子节点;设施数超50时仅加载首字母匹配的公司数据,缩减网格数据量
- 关闭尽可能多控件的ViewState,但WebDataTree依赖ViewState无法关闭
可行解决方案
1. 替换默认JSON序列化机制
ASP.NET内置的JavaScriptSerializer对大量数据的处理存在限制,可改用Newtonsoft.Json替代默认序列化:
- 继承
ScriptManager类,重写RegisterScriptDeserializer方法,注册自定义的Json.NET序列化逻辑 - 在服务端处理AJAX请求时,手动用Json.NET序列化数据,绕过默认序列化器的成员数限制
2. 拆分UpdatePanel,减少单次回传数据
- 将WebDataTree和GridView分别放在独立的UpdatePanel中,取消嵌套结构,避免一次性回传大量ViewState和控件状态数据
- 精准配置UpdatePanel的触发条件:树节点切换时仅更新WebDataTree所在Panel,网格操作时仅更新GridView所在Panel
3. 优化WebDataTree的加载逻辑
- 启用延迟加载:仅在用户手动展开树节点时,才异步加载对应的设施子节点,而非一次性加载所有选中节点的子节点
- 精简WebDataTree的客户端状态:仅保留选中节点ID等核心信息,关闭不必要的状态缓存,减少回传数据体积
4. 放弃UpdatePanel,改用纯AJAX请求
- 替换UpdatePanel的部分回传机制,用jQuery AJAX直接调用WebMethod或ASHX处理程序,获取数据后手动更新DOM
- 这种方式完全可控数据序列化和传输流程,彻底避开ASP.NET内置AJAX框架的限制
5. 验证配置生效细节
- 确认
asp:MaxJsonDeserializerMembers配置在web.config的<appSettings>节点下,且未被其他层级的配置覆盖 - 调整
httpRuntime节点的maxRequestLength和requestLengthDiskThreshold参数,确保请求数据不会因体积过大被截断
内容的提问来源于stack exchange,提问作者Mike Hofer
相关产品推荐
相关产品推荐

