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. var jsonData = GetDeserializedObject(controllerContext);
  10. if (jsonData == null)
  11. {
  12. return null;
  13. }
  14. var backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
  15. var backingStoreWrapper = new EntryLimitedDictionary(backingStore);
  16. AddToBackingStore(backingStoreWrapper, String.Empty, jsonData);
  17. return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);
  18. }
  19. private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)
  20. {
  21. var d = value as IDictionary<string, object>;
  22. if (d != null)
  23. {
  24. foreach (var entry in d)
  25. {
  26. AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value);
  27. }
  28. return;
  29. }
  30. var l = value as IList;
  31. if (l != null)
  32. {
  33. for (var i = 0; i < l.Count; i++)
  34. {
  35. AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]);
  36. }
  37. return;
  38. }
  39. // primitive
  40. backingStore.Add(prefix, value);
  41. }
  42. private static object GetDeserializedObject(ControllerContext controllerContext)
  43. {
  44. if (
  45. !controllerContext.HttpContext.Request.ContentType.StartsWith("application/json",
  46. StringComparison.OrdinalIgnoreCase))
  47. {
  48. // not JSON request
  49. return null;
  50. }
  51. var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
  52. var bodyText = reader.ReadToEnd();
  53. if (String.IsNullOrEmpty(bodyText))
  54. {
  55. // no JSON data
  56. return null;
  57. }
  58. var serializer = new JavaScriptSerializer {MaxJsonLength = int.MaxValue};
  59. var jsonData = serializer.DeserializeObject(bodyText);
  60. return jsonData;
  61. }
  62. private static string MakeArrayKey(string prefix, int index)
  63. {
  64. return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";
  65. }
  66. private static string MakePropertyKey(string prefix, string propertyName)
  67. {
  68. return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName;
  69. }
  70. private class EntryLimitedDictionary
  71. {
  72. private readonly IDictionary<string, object> _innerDictionary;
  73. private int _itemCount;
  74. public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
  75. {
  76. _innerDictionary = innerDictionary;
  77. }
  78. public void Add(string key, object value)
  79. {
  80. if (++_itemCount > MaximumDepth)
  81. {
  82. throw new InvalidOperationException(
  83. "The length of the string exceeds the value set on the maxJsonLength property.");
  84. }
  85. _innerDictionary.Add(key, value);
  86. }
  87. private static int GetMaximumDepth()
  88. {
  89. var appSettings = ConfigurationManager.AppSettings;
  90. var valueArray = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
  91. if (valueArray != null && valueArray.Length > 0)
  92. {
  93. int result;
  94. if (Int32.TryParse(valueArray[0], out result))
  95. {
  96. return result;
  97. }
  98. }
  99. return 1000; // Fallback default
  100. }
  101. private static readonly int MaximumDepth = GetMaximumDepth();
  102. }
  103. }
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. // Increase max Json length
  4. foreach (var factory in ValueProviderFactories.Factories)
  5. {
  6. if (factory is JsonValueProviderFactory)
  7. {
  8. ValueProviderFactories.Factories.Remove(factory as JsonValueProviderFactory);
  9. break;
  10. }
  11. }
  12. ValueProviderFactories.Factories.Add(new CustomJsonValueProviderFactory());
  13. }
Thats all.