JavaScriptSerializer的MaxJsonLength限制是否仅计算JSON结构而非字符串内容?
关于MVC JsonResult大JSON字符串绕过长度限制的疑问解答
先贴出两种实现代码:
//1st way public string GetSomeData() { List<SomeObject> largeCollection = GetLargeDataCollection(); JavaScriptSerializer serializer = new JavaScriptSerializer(); json = serializer.Serialize(largeCollection); // FAILS - MaxJsonLength exceeded OK return json; } //2nd way public string GetData() { List<Data> resData = GetLargeDataCollection(); // Pre-serialize with Newtonsoft (creates ~10MB JSON string) json = JsonConvert.SerializeObject(resData); return json; } [HttpGet] public JsonResult GetUsers() { var Data = GetData(); // 10MB string // This works fine even though MVC's Json() has ~100KB limit return Json(new { data = Data, // 10MB pre-serialized JSON string }, JsonRequestBehavior.AllowGet); }
你的猜测完全正确:当JavaScriptSerializer序列化包含这个10MB预序列化字符串的匿名对象时,只会把该字符串当作单一的字符串值处理,不会解析字符串内部的JSON内容,仅计算JSON结构本身的开销(比如属性名data、括号、引号这些),再加上这个字符串转义后的长度,但核心是——它不会把字符串里的JSON内容拆解开来统计长度,自然不会触发MaxJsonLength限制。
具体来说:
- 第一种方式直接序列化大集合时,JavaScriptSerializer会遍历所有对象、递归解析每个属性,计算最终生成的JSON总长度,这个长度轻松超过默认的100KB限制,所以触发报错。
- 第二种方式里,Newtonsoft已经完成了大集合的序列化,得到的10MB字符串在匿名对象里只是一个普通的属性值。当MVC用JavaScriptSerializer序列化这个匿名对象时,它只需要把这个字符串作为一个整体转义后嵌入JSON结构里,不会去解析字符串内部的JSON内容,所以它检查的总长度是「属性名长度+括号引号等结构长度+转义后的字符串长度」,但JavaScriptSerializer的MaxJsonLength限制是针对当前序列化操作生成的JSON总长度,而不是字符串内容里嵌套的JSON长度。由于这个字符串是作为单一值处理,整个序列化后的内容虽然实际有10MB多,但不会触发限制。
内容的提问来源于stack exchange,提问作者Shad
相关产品推荐
相关产品推荐

