Can I set an unlimited length for maxJsonLength in web.config?

后端 未结 29 3224
礼貌的吻别
礼貌的吻别 2020-11-21 06:43

I am using the autocomplete feature of jQuery. When I try to retrieve the list of more then 17000 records (each won\'t have more than 10 char length), it\'s exceeding the le

29条回答
  •  花落未央
    2020-11-21 07:43

    Alternative ASP.NET MVC 5 Fix:

    (Mine is similar to MFCs answer above with a few small changes)

    I wasn't ready to change to Json.NET just yet and in my case the error was occurring during the request. Best approach in my scenario was modifying the actual JsonValueProviderFactory which applies the fix to the global project and can be done by editing the global.cs file as such.

    JsonValueProviderConfig.Config(ValueProviderFactories.Factories);
    

    add a web.config entry:

    
    

    and then create the two following classes

    public class JsonValueProviderConfig
    {
        public static void Config(ValueProviderFactoryCollection factories)
        {
            var jsonProviderFactory = factories.OfType().Single();
            factories.Remove(jsonProviderFactory);
            factories.Add(new CustomJsonValueProviderFactory());
        }
    }
    

    This is basically an exact copy of the default implementation found in System.Web.Mvc but with the addition of a configurable web.config appsetting value aspnet:MaxJsonLength.

    public class CustomJsonValueProviderFactory : ValueProviderFactory
    {
    
        /// Returns a JSON value-provider object for the specified controller context.
        /// A JSON value-provider object for the specified controller context.
        /// The controller context.
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext");
    
            object deserializedObject = CustomJsonValueProviderFactory.GetDeserializedObject(controllerContext);
            if (deserializedObject == null)
                return null;
    
            Dictionary strs = new Dictionary(StringComparer.OrdinalIgnoreCase);
            CustomJsonValueProviderFactory.AddToBackingStore(new CustomJsonValueProviderFactory.EntryLimitedDictionary(strs), string.Empty, deserializedObject);
    
            return new DictionaryValueProvider(strs, CultureInfo.CurrentCulture);
        }
    
        private static object GetDeserializedObject(ControllerContext controllerContext)
        {
            if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                return null;
    
            string fullStreamString = (new StreamReader(controllerContext.HttpContext.Request.InputStream)).ReadToEnd();
            if (string.IsNullOrEmpty(fullStreamString))
                return null;
    
            var serializer = new JavaScriptSerializer()
            {
                MaxJsonLength = CustomJsonValueProviderFactory.GetMaxJsonLength()
            };
            return serializer.DeserializeObject(fullStreamString);
        }
    
        private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)
        {
            IDictionary strs = value as IDictionary;
            if (strs != null)
            {
                foreach (KeyValuePair keyValuePair in strs)
                    CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);
    
                return;
            }
    
            IList lists = value as IList;
            if (lists == null)
            {
                backingStore.Add(prefix, value);
                return;
            }
    
            for (int i = 0; i < lists.Count; i++)
            {
                CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakeArrayKey(prefix, i), lists[i]);
            }
        }
    
        private class EntryLimitedDictionary
        {
            private static int _maximumDepth;
    
            private readonly IDictionary _innerDictionary;
    
            private int _itemCount;
    
            static EntryLimitedDictionary()
            {
                _maximumDepth = CustomJsonValueProviderFactory.GetMaximumDepth();
            }
    
            public EntryLimitedDictionary(IDictionary innerDictionary)
            {
                this._innerDictionary = innerDictionary;
            }
    
            public void Add(string key, object value)
            {
                int num = this._itemCount + 1;
                this._itemCount = num;
                if (num > _maximumDepth)
                {
                    throw new InvalidOperationException("The length of the string exceeds the value set on the maxJsonLength property.");
                }
                this._innerDictionary.Add(key, value);
            }
        }
    
        private static string MakeArrayKey(string prefix, int index)
        {
            return string.Concat(prefix, "[", index.ToString(CultureInfo.InvariantCulture), "]");
        }
    
        private static string MakePropertyKey(string prefix, string propertyName)
        {
            if (string.IsNullOrEmpty(prefix))
            {
                return propertyName;
            }
            return string.Concat(prefix, ".", propertyName);
        }
    
        private static int GetMaximumDepth()
        {
            int num;
            NameValueCollection appSettings = ConfigurationManager.AppSettings;
            if (appSettings != null)
            {
                string[] values = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
                if (values != null && values.Length != 0 && int.TryParse(values[0], out num))
                {
                    return num;
                }
            }
            return 1000;
        }
    
        private static int GetMaxJsonLength()
        {
            int num;
            NameValueCollection appSettings = ConfigurationManager.AppSettings;
            if (appSettings != null)
            {
                string[] values = appSettings.GetValues("aspnet:MaxJsonLength");
                if (values != null && values.Length != 0 && int.TryParse(values[0], out num))
                {
                    return num;
                }
            }
            return 1000;
        }
    }
    
        

    提交回复
    热议问题