如何设置无限制的maxJsonLength以解决System.OutOfMemoryException?
解决JavaScriptSerializer大数据序列化OutOfMemoryException,实现无限制JSON序列化
嘿,我完全懂你这头疼的处境——之前靠手动设置MaxJsonLength或者改web.config还能对付,结果数据量涨到250k+直接爆内存,简直是踩了序列化的坑。
先说说为啥你之前的方案失效
JavaScriptSerializer本身内存效率极低,序列化大对象时会一次性把整个JSON字符串加载到内存里,哪怕把MaxJsonLength拉满到Int32.MaxValue,也架不住对象层级深、数据量大带来的内存开销,最终触发OutOfMemoryException。- web.config里的
<jsonSerialization>配置只对ASMX服务、WebMethods生效,你在代码里手动实例化的JavaScriptSerializer根本不会读取这个配置,所以改了也白搭。
推荐方案:换用Newtonsoft.Json(Json.NET)
这是.NET生态里最成熟、内存效率最高的JSON序列化库,默认没有强制的长度限制(只要服务器内存足够),而且序列化大对象时的内存占用比JavaScriptSerializer低得多。
具体实现步骤
- 先通过NuGet安装Newtonsoft.Json(如果还没装):
Install-Package Newtonsoft.Json - 在Razor视图里替换序列化逻辑:
@using Newtonsoft.Json @{ // 按需配置序列化规则,比如忽略循环引用、取消深度限制 var jsonSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, MaxDepth = null // 取消默认的64层深度限制,适配大层级对象 }; var jsonModel = JsonConvert.SerializeObject(Model.ModelName, jsonSettings); } - 前端依然用
Html.Raw渲染:var model = @Html.Raw(jsonModel);
备选方案(必须用JavaScriptSerializer时)
如果项目限制不能换库,可以尝试流式序列化减少内存占用,但这种方式比较繁琐:
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); serializer.MaxJsonLength = int.MaxValue; Response.ContentType = "application/json"; // 直接写入响应流,避免一次性加载整个JSON到内存 using (var writer = new StreamWriter(Response.OutputStream)) { serializer.SerializeToWriter(Model.ModelName, writer); }
不过这种方式需要调整视图逻辑,不如换库来得直接。
额外优化建议
- 用DTO精简数据:不要直接序列化完整实体模型,创建只包含前端需要字段的DTO(数据传输对象),减少序列化的数据量。
- 前端分页加载:如果是页面展示,没必要一次性传所有数据,实现分页或滚动加载,既减轻服务器压力,又提升页面速度。
- 处理循环引用:很多内存溢出是因为模型存在循环引用,序列化时会生成无限层级JSON,记得在序列化配置里忽略循环引用。
内容的提问来源于stack exchange,提问作者Ben77
相关产品推荐
相关产品推荐

