修改web.config的MaxJsonLength无效,大JSON请求报错如何解决?
为什么MaxJsonLength设置后没生效?
最常见的原因是web.config的配置节点位置错误。很多人会误把maxJsonLength配置到<system.web>下的<httpRuntime>节点,但这个节点控制的是整个HTTP请求的大小,而非JavaScriptSerializer处理JSON的长度限制。正确的配置节点应该在<system.web.extensions>下的<jsonSerialization>里。
另外,ASP.NET MVC默认的ModelBinder在处理JSON请求时,可能不会读取全局配置的maxJsonLength,或者项目版本存在配置读取问题,导致设置不生效。
解决办法
方法1:正确配置web.config
在web.config的<configuration>节点内添加以下配置,把maxJsonLength设为足够大的值(比如int类型最大值2147483647):
<system.web.extensions> <scripting> <webServices> <jsonSerialization maxJsonLength="2147483647"/> </webServices> </scripting> </system.web.extensions>
同时,为确保整个HTTP请求能容纳大JSON,建议同步调整<httpRuntime>的请求大小限制(按需设置):
<system.web> <httpRuntime maxRequestLength="2147483" requestLengthDiskThreshold="2147483" /> </system.web>
(注:maxRequestLength单位是KB,2147483KB约等于2GB)
方法2:自定义ModelBinder强制设置MaxJsonLength
如果配置仍不生效,可以创建自定义ModelBinder,手动指定JavaScriptSerializer的最大长度:
public class JsonModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var request = controllerContext.HttpContext.Request; if (request.ContentType.Contains("application/json")) { using (var reader = new StreamReader(request.InputStream)) { var json = reader.ReadToEnd(); var serializer = new JavaScriptSerializer(); serializer.MaxJsonLength = int.MaxValue; // 设置最大长度 return serializer.Deserialize(json, bindingContext.ModelType); } } return base.BindModel(controllerContext, bindingContext); } }
然后在Global.asax.cs的Application_Start方法中注册这个ModelBinder:
ModelBinders.Binders.DefaultBinder = new JsonModelBinder();
方法3:改用Json.NET(推荐)
JavaScriptSerializer本身限制较多,改用Json.NET(Newtonsoft.Json)可以彻底避开长度问题,且功能更强大。
- 安装Newtonsoft.Json NuGet包:
Install-Package Newtonsoft.Json
- 创建自定义的Json.NET ModelBinder:
public class JsonNetModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var request = controllerContext.HttpContext.Request; request.InputStream.Position = 0; using (var reader = new StreamReader(request.InputStream)) { var json = reader.ReadToEnd(); return JsonConvert.DeserializeObject(json, bindingContext.ModelType); } } }
- 注册ModelBinder到全局,或直接在控制器方法参数上标注:
// 全局注册(Global.asax.cs的Application_Start) ModelBinders.Binders.Add(typeof(IEnumerable<CanaleDetailed>), new JsonNetModelBinder()); // 或者在控制器方法参数上直接指定 public PartialViewResult RicalcolaRenderCanaliRows([ModelBinder(typeof(JsonNetModelBinder))] IEnumerable<CanaleDetailed> canali) { return PartialView(canali); }
Json.NET没有默认的JSON长度限制,能完全满足大JSON请求需求。
内容的提问来源于stack exchange,提问作者Luigi D'Angelo

