Solved

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

Posted on 2016-11-15
5
350 Views
Last Modified: 2016-11-17
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
Comment
Question by:ccravenbartle
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 56

Expert Comment

by:Julian Hansen
ID: 41888231
Have you tried this
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.MaxJsonLength = int.MaxValue;
...
return jss.Serialize(yourDataObject);.

Open in new window

0
 

Author Comment

by:ccravenbartle
ID: 41888301
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
 
LVL 56

Expert Comment

by:Julian Hansen
ID: 41888312
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
 

Author Comment

by:ccravenbartle
ID: 41888323
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
 
LVL 82

Accepted Solution

by:
leakim971 earned 500 total points
ID: 41888685
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

Technology Partners: 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!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
testing a web application for ipad on windows pc 3 38
Rotate images for Web Page 11 27
Use Mid in Html 6 22
AJAx/JQuery/JSON Error 3 11
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question