Search code examples
c#ajaxasp.net-mvcjsonresult

the length of the string exceeds the value set on the maxjsonlength property in mvc


I am using ajax call to get vehicle trip details . So while returning trip details from controller to view I am getting the error "the length of the string exceeds the value set on the maxjsonlength property".

below given is the ajax call i am using to get trip details. Whenever the trip details are huge its going to the error function .

    function LoadTripModalWindow(masterID, headwayPlanID, version, specialDay, applicableDay) {
        //change this value after cpp service implementation
        //version = 1;
        /////////////////
       if (headwayPlanID == 0 || headwayPlanID == null) {
            $('#HeadwayPopUp').hide();
            $('#NoTripGenerated').hide();
            $('#NoHeadwayPopUp').show();
        }
        else {
            $('#tripDialogDiv').hide();
            $('#NoHeadwayPopUp').hide();
            $.blockUI({ message: $('#msthrobber') });
            var tripIn = '';
            tripIn = '<table class="table table-bordered trip" id="tripInTableMS"> </table>';
            $("#tripInTableMS").remove();
            $("#TripIn").append(tripIn);
            var tripOut = '';
            tripOut = '<table class="table table-bordered trip" id="tripOutTableMS"> </table>';
            $("#tripOutTableMS").remove();
            $("#TripOut").append(tripOut);
            $.ajax({
                type: "GET",
                url: "/ScheduleManagement/MasterConfiguration/GetTripTableDetails/",
                data: { version: version, masterScheduleID: masterID, headwayPlanId: headwayPlanID, applicableDay: applicableDay, specialDay: specialDay },
                dataType: "json",
                context: this,
                success: function (data) {
                    var returnedData = JSON.parse(data);
                    var tripIn = returnedData.TripIn;
                    var tripOut = returnedData.TripOut;
                    var TripInHeadwayPlan = returnedData.TripInHeadwayPlan;
                    var TripOutHeadwayPlan = returnedData.TripOutHeadwayPlan;
                    var TripInRoute = returnedData.TripInRoute;
                    var TripOutRoute = returnedData.TripOutRoute;
                    var ShiftDetails = returnedData.AssignedShifts;
                    if ((tripIn == null || tripIn.length == 0) && (tripOut == null || tripOut.length == 0)) {
                        //if (tripIn == null && tripOut == null) {

                        $.unblockUI();
                        $('#tripDialogDiv').show();
                        $('#HeadwayPopUp').hide();
                        $('#NoTripGenerated').show();
                    }
                    else {
                        var shiftDetail = '<label"> Shift Details :</label>&nbsp;&nbsp;&nbsp;';
                        for (var s = 0; s < ShiftDetails.length; s++) {
                            shiftDetail += '&nbsp;<input type="text" class="shift-details  Shift' + (parseInt(s) + 1) + ' " disabled>' +
                             '<label  style="color: slategrey;">' + ShiftDetails[s].shiftName + '(' + ShiftDetails[s].startTime.substring(0, 5) + ' - ' + ShiftDetails[s].endTime.substring(0, 5) + ')</label> &nbsp; &nbsp;';
                        }
                        $("#ShiftDetails").html('');
                        $("#ShiftDetails").append(shiftDetail);
                        if (tripIn != null) {
                            var tripInTable = new triptable('tripInTableMS', '0', 'btnAddCol1', 'btnTripSave', 'btnTrip1Remove', tripIn, TripInHeadwayPlan, TripInRoute, TripOutRoute, ShiftDetails);
                        }
                        if (tripOut != null) {
                            var tripOutTable = new triptable('tripOutTableMS', '1', 'btnAddCol2', 'btnTripSave', 'btnTrip2Remove', tripOut, TripOutHeadwayPlan, TripInRoute, TripOutRoute, ShiftDetails);
                        }
                        $.unblockUI();
                        $('#tripDialogDiv').show();
                        $('#HeadwayPopUp').show();
                        $('#NoTripGenerated').hide();
                        $("#TripInBox").show();
                        $("#TripOutBox").hide();
                    }
                },
                error: function (response) {
                    alert("error : " + response);
                }
            });
        }
    }

I have added below code in my application.

 private static void AddToBackingStore(JsonDotNetValueProviderFactory.EntryLimitedDictionary backingStore, string prefix, object value)
        {
            IDictionary<string, object> dictionary = value as IDictionary<string, object>;
            if (dictionary != null)
            {
                foreach (KeyValuePair<string, object> keyValuePair in (IEnumerable<KeyValuePair<string, object>>)dictionary)
                    JsonDotNetValueProviderFactory.AddToBackingStore(backingStore, JsonDotNetValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);
            }
            else
            {
                IList list = value as IList;
                if (list != null)
                {
                    for (int index = 0; index < list.Count; ++index)
                        JsonDotNetValueProviderFactory.AddToBackingStore(backingStore, JsonDotNetValueProviderFactory.MakeArrayKey(prefix, index), list[index]);
                }
                else
                    backingStore.Add(prefix, value);
            }
        }

        private static object GetDeserializedObject(ControllerContext controllerContext)
        {
            if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                return (object)null;
            string end = new StreamReader(controllerContext.HttpContext.Request.InputStream).ReadToEnd();
            if (string.IsNullOrEmpty(end))
                return (object)null;

            var serializer = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue };

            return serializer.DeserializeObject(end);
        }
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext");
            object deserializedObject = JsonDotNetValueProviderFactory.GetDeserializedObject(controllerContext);
            if (deserializedObject == null)
                return (IValueProvider)null;
            Dictionary<string, object> dictionary = new Dictionary<string, object>((IEqualityComparer<string>)StringComparer.OrdinalIgnoreCase);
            JsonDotNetValueProviderFactory.AddToBackingStore(new JsonDotNetValueProviderFactory.EntryLimitedDictionary((IDictionary<string, object>)dictionary), string.Empty, deserializedObject);
            return (IValueProvider)new DictionaryValueProvider<object>((IDictionary<string, object>)dictionary, CultureInfo.CurrentCulture);

        }
        private static string MakeArrayKey(string prefix, int index)
        {
            return prefix + "[" + index.ToString((IFormatProvider)CultureInfo.InvariantCulture) + "]";
        }

        private static string MakePropertyKey(string prefix, string propertyName)
        {
            if (!string.IsNullOrEmpty(prefix))
                return prefix + "." + propertyName;
            return propertyName;
        }

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

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

            public void Add(string key, object value)
            {
                if (++this._itemCount > JsonDotNetValueProviderFactory.EntryLimitedDictionary._maximumDepth)
                    throw new InvalidOperationException("JsonValueProviderFactory_RequestTooLarge");
                this._innerDictionary.Add(key, value);
            }

            private static int GetMaximumDepth()
            {
                NameValueCollection appSettings = ConfigurationManager.AppSettings;
                if (appSettings != null)
                {
                    string[] values = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
                    int result;
                    if (values != null && values.Length > 0 && int.TryParse(values[0], out result))
                        return result;
                }
                return 1000;
            }
        }

And in global.ascx file I have added below lines

  foreach (var factory in ValueProviderFactories.Factories)
            {
                if (factory.GetType().FullName == "System.Web.Mvc.JsonValueProviderFactory")
                {
                    jsonFactory = factory;
                    break;
                }
            }

            if (jsonFactory != null)
            {
                ValueProviderFactories.Factories.Remove(jsonFactory);
            }

            ValueProviderFactories.Factories.Add(new JsonDotNetValueProviderFactory());

It was working fine for few months. Now again the data length increased and started to getting the error again.

Please let me know if anybody have any suggestion to solve this issue.


Solution

  • Json result have some default length. Whenever it exceeds, it throw above error.

    For this you have 2 approach either add length in web.config or while return your action method define length.

    for Web.config

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

    or while return jsonresult in Controller method, define return length as max length of your string.

    return new JsonResult()
                {
                    ContentEncoding = Encoding.Default,
                    ContentType = "application/json",
                    Data = data,
                    JsonRequestBehavior = requestBehavior,
                    MaxJsonLength = int.MaxValue
                };
    

    Please refer The length of the string exceeds the value set on the maxJsonLength property

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