Handle Max JSON Length Property In C#

Recently, I faced this problem. When the data from my client side is more than 5 MB, it does not hit my MVC Controller; instead, it steps out and shows an error because it has exceeded the max JSON length.

But finally, I got the solution. So, I thought I should share it so that more people can benefit. There are basically 3 steps to do that.

Step1 

Set in the webconfig file,

<add key="aspnet:MaxJsonDeserializerMembers" value="550000"/>

Step2

Add the below code in app_start folder, or just download the attached file and paste it in your app_start folder.
  1. public sealed class CustomJsonValueProviderFactory : ValueProviderFactory  
  2.     {  
  3.         public override IValueProvider GetValueProvider(ControllerContext controllerContext)  
  4.         {  
  5.             if (controllerContext == null)  
  6.             {  
  7.                 throw new ArgumentNullException("controllerContext");  
  8.             }  
  9.   
  10.             var jsonData = GetDeserializedObject(controllerContext);  
  11.             if (jsonData == null)  
  12.             {  
  13.                 return null;  
  14.             }  
  15.   
  16.             var backingStore = new Dictionary<stringobject>(StringComparer.OrdinalIgnoreCase);  
  17.             var backingStoreWrapper = new EntryLimitedDictionary(backingStore);  
  18.             AddToBackingStore(backingStoreWrapper, String.Empty, jsonData);  
  19.             return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);  
  20.         }  
  21.   
  22.         private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)  
  23.         {  
  24.             var d = value as IDictionary<stringobject>;  
  25.             if (d != null)  
  26.             {  
  27.                 foreach (var entry in d)  
  28.                 {  
  29.                     AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value);  
  30.                 }  
  31.                 return;  
  32.             }  
  33.   
  34.             var l = value as IList;  
  35.             if (l != null)  
  36.             {  
  37.                 for (var i = 0; i < l.Count; i++)  
  38.                 {  
  39.                     AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]);  
  40.                 }  
  41.                 return;  
  42.             }  
  43.   
  44.             // primitive  
  45.             backingStore.Add(prefix, value);  
  46.         }  
  47.   
  48.         private static object GetDeserializedObject(ControllerContext controllerContext)  
  49.         {  
  50.             if (  
  51.                 !controllerContext.HttpContext.Request.ContentType.StartsWith("application/json",  
  52.                     StringComparison.OrdinalIgnoreCase))  
  53.             {  
  54.                 // not JSON request  
  55.                 return null;  
  56.             }  
  57.   
  58.             var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);  
  59.             var bodyText = reader.ReadToEnd();  
  60.             if (String.IsNullOrEmpty(bodyText))  
  61.             {  
  62.                 // no JSON data  
  63.                 return null;  
  64.             }  
  65.   
  66.             var serializer = new JavaScriptSerializer {MaxJsonLength = int.MaxValue};  
  67.   
  68.             var jsonData = serializer.DeserializeObject(bodyText);  
  69.             return jsonData;  
  70.         }  
  71.   
  72.         private static string MakeArrayKey(string prefix, int index)  
  73.         {  
  74.             return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";  
  75.         }  
  76.   
  77.         private static string MakePropertyKey(string prefix, string propertyName)  
  78.         {  
  79.             return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName;  
  80.         }  
  81.   
  82.         private class EntryLimitedDictionary  
  83.         {  
  84.             private readonly IDictionary<stringobject> _innerDictionary;  
  85.             private int _itemCount;  
  86.   
  87.             public EntryLimitedDictionary(IDictionary<stringobject> innerDictionary)  
  88.             {  
  89.                 _innerDictionary = innerDictionary;  
  90.             }  
  91.   
  92.             public void Add(string key, object value)  
  93.             {  
  94.                 if (++_itemCount > MaximumDepth)  
  95.                 {  
  96.                     throw new InvalidOperationException(  
  97.                         "The length of the string exceeds the value set on the maxJsonLength property.");  
  98.                 }  
  99.   
  100.                 _innerDictionary.Add(key, value);  
  101.             }  
  102.   
  103.             private static int GetMaximumDepth()  
  104.             {  
  105.                 var appSettings = ConfigurationManager.AppSettings;  
  106.   
  107.                 var valueArray = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");  
  108.                 if (valueArray != null && valueArray.Length > 0)  
  109.                 {  
  110.                     int result;  
  111.                     if (Int32.TryParse(valueArray[0], out result))  
  112.                     {  
  113.                         return result;  
  114.                     }  
  115.                 }  
  116.   
  117.                 return 1000; // Fallback default  
  118.             }  
  119.   
  120.             private static readonly int MaximumDepth = GetMaximumDepth();  
  121.         }  
  122.     }  
Step 3

Add the following code in global.asax under protected void Application_Start()
 for a better appearance. I have removed the other code.
  1. protected void Application_Start()  
  2. {  
  3.    
  4.   // Increase max Json length  
  5. foreach (var factory in ValueProviderFactories.Factories)  
  6. {  
  7.    if (factory is JsonValueProviderFactory)  
  8.    {  
  9.    ValueProviderFactories.Factories.Remove(factory as JsonValueProviderFactory);  
  10.    break;  
  11.    }  
  12. }  
  13. ValueProviderFactories.Factories.Add(new CustomJsonValueProviderFactory());  
  14.    
  15. }   
Thats all.