JsonMaxLength exception on deserializing large json objects JsonMaxLength exception on deserializing large json objects json json

JsonMaxLength exception on deserializing large json objects


The built-in JsonValueProviderFactory ignores the <jsonSerialization maxJsonLength="50000000"/> setting. So you could write a custom factory by using the built-in implementation:

public sealed class MyJsonValueProviderFactory : ValueProviderFactory{    private static void AddToBackingStore(Dictionary<string, object> backingStore, string prefix, object value)    {        IDictionary<string, object> d = value as IDictionary<string, object>;        if (d != null)        {            foreach (KeyValuePair<string, object> entry in d)            {                AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value);            }            return;        }        IList l = value as IList;        if (l != null)        {            for (int i = 0; i < l.Count; i++)            {                AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]);            }            return;        }        // primitive        backingStore[prefix] = value;    }    private static object GetDeserializedObject(ControllerContext controllerContext)    {        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))        {            // not JSON request            return null;        }        StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);        string bodyText = reader.ReadToEnd();        if (String.IsNullOrEmpty(bodyText))        {            // no JSON data            return null;        }        JavaScriptSerializer serializer = new JavaScriptSerializer();        serializer.MaxJsonLength = 2147483647;        object jsonData = serializer.DeserializeObject(bodyText);        return jsonData;    }    public override IValueProvider GetValueProvider(ControllerContext controllerContext)    {        if (controllerContext == null)        {            throw new ArgumentNullException("controllerContext");        }        object jsonData = GetDeserializedObject(controllerContext);        if (jsonData == null)        {            return null;        }        Dictionary<string, object> backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);        AddToBackingStore(backingStore, String.Empty, jsonData);        return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);    }    private static string MakeArrayKey(string prefix, int index)    {        return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";    }    private static string MakePropertyKey(string prefix, string propertyName)    {        return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName;    }}

The only modification I did compared to the default factory is adding the following line:

serializer.MaxJsonLength = 2147483647;

Unfortunately this factory is not extensible at all, sealed stuff so I had to recreate it.

and in your Application_Start:

ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<System.Web.Mvc.JsonValueProviderFactory>().FirstOrDefault());ValueProviderFactories.Factories.Add(new MyJsonValueProviderFactory());


I found that the maxRequestLength did not solve the problem however.I resolved my issue with the below setting. It is cleaner than having to implement a custom ValueProviderFactory

<appSettings>  <add key="aspnet:MaxJsonDeserializerMembers" value="150000" /></appSettings>

Credit goes to the following questions:

JsonValueProviderFactory throws "request too large"

Getting "The JSON request was too large to be deserialized"

This setting obviously relates to a highly complex json model and not the actual size.


The solution of Darin Dimitrov works for me but i need reset the position of the stream of the request before read it, adding this line:

controllerContext.HttpContext.Request.InputStream.Position = 0;

So now, the method GetDeserializedObject looks like this:

 private static object GetDeserializedObject(ControllerContext controllerContext)    {        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))        {            // not JSON request            return null;        }        controllerContext.HttpContext.Request.InputStream.Position = 0;        StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);        string bodyText = reader.ReadToEnd();        if (String.IsNullOrEmpty(bodyText))        {            // no JSON data            return null;        }        JavaScriptSerializer serializer = new JavaScriptSerializer();        serializer.MaxJsonLength = 2147483647;        object jsonData = serializer.DeserializeObject(bodyText);        return jsonData;    }