使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength 属性设置的值
Type : System.InvalidOperationException, mscorlib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : 使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串
的长度超过了为 maxJsonLength 属性设置的值。
Source : System.Web.Extensions
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Void Serialize(System.Object, System.Text.StringBuilder,
SerializationFormat)
Stack Trace : 在
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj,
StringBuilder output, SerializationFormat serializationFormat)
在 System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat)
在 System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object
这个异常是在执行MVC中的JsonResult的时抛出的,根据异常的Message得知是序列化的字符串超出了maxJsonLength的限制。并得知这个属性是由JavaScriptSerializer提供的,因为MVC内置的JsonResult是用JavaScriptSerializer进行序列化的。在网上快速搜索了一下,碰到这个问题的童鞋不少,大部分推荐的解决的方法都是在web.config中加入以下配置,设置maxJsonLength的长度即可。

<system.web.extensions> <scripting> <webServices> <jsonSerialization maxJsonLength="20971520"/> </webServices> </scripting> </system.web.extensions>
在自动提示下,很顺畅的加上了几行代码,以为这是个简洁的解决方案,但是运行网站之后报以下错误:
分析器错误消息: 无法识别的配置节 system.web.extensions。
这似乎又是碰到了一家人不认识的情况,既然无法识别为什么能带智能感知的方式输出,而且是已system.web开头的,按道理不会识别不出的。以为是拼写错误,经过进一步搜索之后,原来是缺乏了声明,加上对节点的声明即可(很大一串的内容)。

<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/> <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> </sectionGroup> </sectionGroup> </sectionGroup>
加入了声明之后,运行正常,但是问题依旧还在,而且不管maxJsonLength设置成多大都无效,就算改成1个字符,居然还能跑起来。碰到这个问题只能进一步的搜索。在这篇文章中找到了原委http://weblogs.asp.net/rashid/archive/2009/03/23/submitting-my-first-bug-after-asp-net-mvc-1-0-rtm-release.aspx。
原来MVC框架内置的JsonResult代码中,在使用JavaScriptSerializer时,都是采用的默认值,没有从maxJsonLength读取值,即忽略了这个配置。要想使用配置中的值,只能自定义一个JsonResult,重写原JsonResult的ExecuteResult方法,于是定义一个ConfigurableJsonResult,代码如下:

public class ConfigurableJsonResult : JsonResult { public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet."); } HttpResponseBase response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) { response.ContentType = ContentType; } else { response.ContentType = "application/json"; } if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } if (Data != null) { JavaScriptSerializer serializer = new JavaScriptSerializer(); ScriptingJsonSerializationSection section = ConfigurationManager.GetSection("system.web.extensions/scripting/webServices/jsonSerialization") as ScriptingJsonSerializationSection; if (section != null) { serializer.MaxJsonLength = section.MaxJsonLength; serializer.RecursionLimit = section.RecursionLimit; } response.Write(serializer.Serialize(Data)); } } }
这样在返回长字符内容的json结果时,直接替换原JsonResult即可,同时也兼顾了可配置的灵活性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结