Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1565
  • Last Modified:

maxJsonLength exceeded error on ajax Post to ASP.NET MVC Controller Action method

I am getting the following error when my javascript attempts to execute the SaveUserCostCentreList MVC Controller Action using $.ajax Post.  The error gets displayed before I can step into the method on the Server Controller.

Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.
Parameter name: input


I have tried setting the maxJsonLength property and other properties relating to data sizes within the web.config but nothing works.

Server side, client side and web config snippets are listed below.


SERVER SIDE

[HttpPost]
        public ActionResult SaveUserCostCentreList(UserVM userVm)
        {
           // error message is displayed without this ever getting executed
           // do stuff with userVm

        }

Open in new window


CLIENT SIDE

 $.ajax({
          url: '@Url.Action("SaveUserCostCentreList", "Admin")',
          data: jsonString,
          type: 'POST',
          contentType: 'application/json',
          dataType: 'json',
           success: function (result) {
                   alert('ok');
               }
          }); 

Open in new window



WEB.CONFIG entries

 <system.web>
    <httpHandlers />
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5">
      <assemblies>
        <add assembly="Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
        <add assembly="System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
     </assemblies>
      <buildProviders />
    </compilation>
    <httpRuntime maxRequestLength="2000000000" />       
  </system.web>

  <system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization maxJsonLength="2147483647">
        </jsonSerialization>
      </webServices>
    </scripting>
  </system.web.extensions>

  <system.webServer>
    <httpProtocol />
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="10485760" />
      </requestFiltering>
    </security>
  </system.webServer>

Open in new window

0
ccravenbartle
Asked:
ccravenbartle
  • 2
  • 2
1 Solution
 
Julian HansenCommented:
Have you tried this
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.MaxJsonLength = int.MaxValue;
...
return jss.Serialize(yourDataObject);.

Open in new window

0
 
ccravenbartleAuthor Commented:
Hi Julian  - thank you for your quick response.

Please clarify.   Is this code which I have to add to the server Controller SaveUserCostCentreList method?  I am uploading my json object view model to the controller using POST,  Is this not applicable to server Get requests rather than server Post requests?  

JavaScriptSerializer jss = new JavaScriptSerializer();
jss.MaxJsonLength = int.MaxValue;
...
return jss.Serialize(yourDataObject);.

Charles
0
 
Julian HansenCommented:
Are you getting the error on the upload - I thought it was the download - did not read the question properly.

What does your .Net service code look like?
0
 
ccravenbartleAuthor Commented:
Yes, it is on the upload.  The method call works fine if I chop the data in half so I know there is nothing wrong with the Controller Action method itself.

[HttpPost]
         public ActionResult SaveUserCostCentreList(UserVM userVm)
         {
            // error message is displayed without this ever getting executed
            // do stuff with userVm

         }
0
 
leakim971PluritechnicianCommented:
We use this file to create a custom JsonValueProviderFactory :
We need to change MaxJsonLength property
From here it is set by default to 2097152 (2*1024*1024 = 2MB), check line 50 :

CustomJsonValueProviderFactory.js :
using System.Web.Mvc;

namespace YourNameSpace
{
    public sealed class CustomJsonValueProviderFactory : ValueProviderFactory
    {
        private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)
        {
            IDictionary<string, object> d = value as IDictionary<string, object>;
            if (d != null)
            {
                foreach (KeyValuePair<string, object> 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;
            }

            JavaScriptSerializer serializer = new JavaScriptSerializer();
            serializer.MaxJsonLength = int.MaxValue;

            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<string, object> backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            EntryLimitedDictionary backingStoreWrapper = new EntryLimitedDictionary(backingStore);
            AddToBackingStore(backingStoreWrapper, String.Empty, jsonData);
            return new DictionaryValueProvider<object>(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;
        }

        private class EntryLimitedDictionary
        {
            private static int _maximumDepth = GetMaximumDepth();
            private readonly IDictionary<string, object> _innerDictionary;
            private int _itemCount = 0;

            public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
            {
                _innerDictionary = innerDictionary;
            }

            public void Add(string key, object value)
            {
                if (++_itemCount > _maximumDepth)
                {
                    throw new InvalidOperationException(MvcResources.JsonValueProviderFactory_RequestTooLarge);
                }

                _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
            }
        }
    }
}
         

Open in new window

 

Open your Global.asax.cs to replace the default JsonValueProviderFactory by the custom one :

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            /
            foreach(var factory in ValueProviderFactories.Factories)
            {
                if(factory is JsonValueProviderFactory)
                {
                    ValueProviderFactories.Factories.Remove(factory as JsonValueProviderFactory);
                    break;
                }
            }
            ValueProviderFactories.Factories.Add(new CustomJsonValueProviderFactory());
        }

Open in new window

0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now