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.
- public sealed class CustomJsonValueProviderFactory : ValueProviderFactory
- {
- public override IValueProvider GetValueProvider(ControllerContext controllerContext)
- {
- if (controllerContext == null)
- {
- throw new ArgumentNullException("controllerContext");
- }
-
- var jsonData = GetDeserializedObject(controllerContext);
- if (jsonData == null)
- {
- return null;
- }
-
- var backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
- var backingStoreWrapper = new EntryLimitedDictionary(backingStore);
- AddToBackingStore(backingStoreWrapper, String.Empty, jsonData);
- return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);
- }
-
- private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)
- {
- var d = value as IDictionary<string, object>;
- if (d != null)
- {
- foreach (var entry in d)
- {
- AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value);
- }
- return;
- }
-
- var l = value as IList;
- if (l != null)
- {
- for (var i = 0; i < l.Count; i++)
- {
- AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]);
- }
- return;
- }
-
-
- backingStore.Add(prefix, value);
- }
-
- private static object GetDeserializedObject(ControllerContext controllerContext)
- {
- if (
- !controllerContext.HttpContext.Request.ContentType.StartsWith("application/json",
- StringComparison.OrdinalIgnoreCase))
- {
-
- return null;
- }
-
- var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
- var bodyText = reader.ReadToEnd();
- if (String.IsNullOrEmpty(bodyText))
- {
-
- return null;
- }
-
- var serializer = new JavaScriptSerializer {MaxJsonLength = int.MaxValue};
-
- var jsonData = serializer.DeserializeObject(bodyText);
- return jsonData;
- }
-
- 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;
- }
-
- private class EntryLimitedDictionary
- {
- private readonly IDictionary<string, object> _innerDictionary;
- private int _itemCount;
-
- public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
- {
- _innerDictionary = innerDictionary;
- }
-
- public void Add(string key, object value)
- {
- if (++_itemCount > MaximumDepth)
- {
- throw new InvalidOperationException(
- "The length of the string exceeds the value set on the maxJsonLength property.");
- }
-
- _innerDictionary.Add(key, value);
- }
-
- private static int GetMaximumDepth()
- {
- var appSettings = ConfigurationManager.AppSettings;
-
- var valueArray = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
- if (valueArray != null && valueArray.Length > 0)
- {
- int result;
- if (Int32.TryParse(valueArray[0], out result))
- {
- return result;
- }
- }
-
- return 1000;
- }
-
- private static readonly int MaximumDepth = GetMaximumDepth();
- }
- }
Step 3
Add the following code in global.asax under protected void Application_Start() for a better appearance. I have removed the other code.
- protected void Application_Start()
- {
-
-
- foreach (var factory in ValueProviderFactories.Factories)
- {
- if (factory is JsonValueProviderFactory)
- {
- ValueProviderFactories.Factories.Remove(factory as JsonValueProviderFactory);
- break;
- }
- }
- ValueProviderFactories.Factories.Add(new CustomJsonValueProviderFactory());
-
- }
Thats all.