ASP.NET MVC3中如何解决JavaScriptSerializer超出maxJsonLength异常?
解决MVC3中TryUpdateModel处理大JSON数据时的序列化长度限制问题
我之前也踩过MVC3处理大JSON请求的坑,你遇到的这个InvalidOperationException确实是默认JavaScriptSerializer的字符串长度限制导致的,而且光改web.config有时候因为节点位置或MVC3的特殊处理,不一定能生效。给你几个可行的解决思路:
1. 确保web.config配置正确(两个关键节点缺一不可)
很多人只改了其中一处,导致配置不生效,要同时配置这两个节点:
(1)设置全局最大请求长度
在<system.web>节点下添加或修改httpRuntime,控制整个POST请求的大小(单位为KB):
<system.web> <httpRuntime maxRequestLength="10240" /> <!-- 这里设为10MB,可根据你的数据大小调整 --> </system.web>
(2)设置JSON序列化的最大长度
在<system.web.extensions>节点下配置jsonSerialization,如果没有这个节点需要先创建:
<system.web.extensions> <scripting> <webServices> <jsonSerialization maxJsonLength="2147483647" /> <!-- 设置为int类型最大值,足够覆盖9K行数据的长度 --> </webServices> </scripting> </system.web.extensions>
2. 手动处理JSON反序列化(配置不生效时的快速解决方案)
有时候MVC3的模型绑定器不会自动读取web.config的maxJsonLength配置,这时候可以跳过默认的TryUpdateModel,手动处理JSON数据:
// 先读取请求中的原始JSON字符串 var jsonContent = new StreamReader(Request.InputStream).ReadToEnd(); // 创建自定义的JavaScriptSerializer并设置最大长度 var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); serializer.MaxJsonLength = int.MaxValue; // 反序列化为你的模型对象 var targetModel = serializer.Deserialize<YourModelType>(jsonContent); // 手动验证模型状态(替代TryUpdateModel的验证逻辑) ModelState.Clear(); TryValidateModel(targetModel); if (ModelState.IsValid) { // 执行你的业务逻辑 }
3. 自定义模型绑定器(长期全局解决方案)
如果你的项目经常需要处理大JSON请求,可以自定义一个模型绑定器,全局设置序列化长度:
public class LargeJsonModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var request = controllerContext.HttpContext.Request; // 仅处理JSON类型的请求 if (request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) { var jsonString = new StreamReader(request.InputStream).ReadToEnd(); var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); serializer.MaxJsonLength = int.MaxValue; return serializer.Deserialize(jsonString, bindingContext.ModelType); } // 非JSON请求使用默认绑定逻辑 return base.BindModel(controllerContext, bindingContext); } }
然后在Global.asax的Application_Start方法中注册这个绑定器:
protected void Application_Start() { ModelBinders.Binders.DefaultBinder = new LargeJsonModelBinder(); }
我当初就是用第二种方法快速解决了问题,后来换成自定义绑定器方便全局复用,你可以根据自己的场景选择合适的方案。
内容的提问来源于stack exchange,提问作者Aritra Nandy
相关产品推荐
相关产品推荐

