Solved

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

Posted on 2016-11-15
5
172 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
  • 2
  • 2
5 Comments
 
LVL 54

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 54

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

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

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

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
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.
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…

772 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