using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Configuration; using System.Globalization; using System.IO; using System.Web.Mvc; using System.Web.Script.Serialization; namespace EnVisage.Code { // this code was taken from https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/JsonValueProviderFactory.cs public class AdvancedJsonValueProviderFactory : ValueProviderFactory { private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value) { IDictionary d = value as IDictionary; if (d != null) { foreach (KeyValuePair 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.Add(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; } // original code starts // JavaScriptSerializer serializer = new JavaScriptSerializer(); // original code ends // modified code starts JavaScriptSerializer serializer = new JavaScriptSerializer() { // added by EN to extend original JsonValueProviderFactory class MaxJsonLength = GetMaxJsonLength() }; // modified code ends 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 backingStore = new Dictionary(StringComparer.OrdinalIgnoreCase); EntryLimitedDictionary backingStoreWrapper = new EntryLimitedDictionary(backingStore); AddToBackingStore(backingStoreWrapper, String.Empty, jsonData); return new DictionaryValueProvider(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; } // added by EN to extend original JsonValueProviderFactory class code starts private static int GetMaxJsonLength() { var maxJsonLengthDefault = (new JavaScriptSerializer()).MaxJsonLength; if (ConfigurationManager.AppSettings == null) return maxJsonLengthDefault; var values = ConfigurationManager.AppSettings.GetValues("MaxJsonLength"); if (values == null || values.Length <= 0) return maxJsonLengthDefault; var maxJsonLength = 0; if (int.TryParse(values[0], out maxJsonLength) && maxJsonLength > 0) return maxJsonLength; return maxJsonLengthDefault; } // added by EN to extend original JsonValueProviderFactory class code ends private class EntryLimitedDictionary { private static int _maximumDepth = GetMaximumDepth(); private readonly IDictionary _innerDictionary; private int _itemCount = 0; public EntryLimitedDictionary(IDictionary innerDictionary) { _innerDictionary = innerDictionary; } public void Add(string key, object value) { if (++_itemCount > _maximumDepth) { throw new InvalidOperationException("Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property."); } _innerDictionary.Add(key, value); } private static int GetMaximumDepth() { NameValueCollection appSettings = ConfigurationManager.AppSettings; if (appSettings != null) { string[] valueArray = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers"); if (valueArray != null && valueArray.Length > 0) { int result; if (Int32.TryParse(valueArray[0], out result)) { return result; } } } return 1000; // Fallback default } } } }