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

30

735

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 length and throws the error:

Exception information:
Exception type: InvalidOperationException
Exception message: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.

Can I set an unlimited length for maxJsonLength in web.config? If not, what is the maximum length I can set?

Mcmillen answered 20/7, 2009 at 6:38 Comment(1)
Something to mention which may be pretty obvious so please excuse me if you've already thought if it; the Json string also includes the curly brackets around each record, the quotation marks around each field name [and value], as well as the field name and value. So it may be useful to set the field name as a single character and also make sure that if the value is not a string, that you set the field type correctly so it doesn't contain quotation marks.Pleading
E
802

NOTE: this answer applies only to Web services, if you are returning JSON from a Controller method, make sure you read this SO answer below as well: https://mcmap.net/q/63344/-can-i-set-an-unlimited-length-for-maxjsonlength-in-web-config


The MaxJsonLength property cannot be unlimited, is an integer property that defaults to 102400 (100k).

You can set the MaxJsonLength property on your web.config:

<configuration> 
   <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
</configuration> 
Eagre answered 20/7, 2009 at 6:43 Comment(14)
It is an integer so the max value you can set is: 2147483644Donovan
@despart: You mean 2 147 483 647.Maitilde
@kmcc049, IMO the values aren't wrong because if you look at the question, the OP is not asking "what's the default value of maxJsonLength?" (BTW, the second most voted answer is answering this, wrong question), he's trying to set this property to "unlimited", but since is an Integer, the maximum value possible is 2147483647 as @depsart and @Descár point out.Inspector
Great but note @David Murdoch's answer below if you're having this problem when using MVC's return Json() or somethingSwor
@ Dercsár: whats the point? 2147483644 is the biggest integer perfectly divisible by 1024.Fidele
Unfortunately this way doesn't work for asp.net mvc. (weblogs.asp.net/rashid/archive/2009/03/23/…). You need to rewrite JsonResult for fix.Depilate
@MirceaChirea - reminiscent of that famous misattributed Bill Gates quote: "640K ought to be enough for anybody!"Barbirolli
This resolved my issue when using an aspx "Page Method" which are the static methods decorated with a [WebMethod] attribute.Charitycharivari
I have this problem in the model binding of JSON to an array of objects. If I am to believe Chrome, the content-length is 2962693. So, no way my JSON was longer that 2147483644 that I specified in the CONFIG. So, this doesn't work for my case either. :(Pepito
I have set the value 2147483644 in web.config but it is still giving me error of serialization.Hardesty
The MSDN page says it's limited to 2097152 (4MB) not 102400. Has it been changed ?Prentiss
@naveen 2 147 482 624 (=2^31 - 1024) is the biggest integer perfectly divisible by 1024. Your 2 147 483 644 (= 2^31 - 4) leaves a rest of 1020 (so it is only perfectly divisible by 4).Zee
Didn't work? Try this instead: https://mcmap.net/q/64438/-getting-quot-the-json-request-was-too-large-to-be-deserialized-quotFinegan
This worked for me in a MVC 4.7 solution. I added the config entry at the end of the configuration section: <configuration> .... .... .... <system.web.extensions> <scripting> <webServices> <jsonSerialization maxJsonLength="50000000"/> </webServices> </scripting> </system.web.extensions> </configuration>Punk
E
516

If you are using MVC 4, be sure to check out this answer as well.


If you are still receiving the error:

  • after setting the maxJsonLength property to its maximum value in web.config
  • and you know that your data's length is less than this value
  • and you are not utilizing a web service method for the JavaScript serialization

your problem is is likely that:

The value of the MaxJsonLength property applies only to the internal JavaScriptSerializer instance that is used by the asynchronous communication layer to invoke Web services methods. (MSDN: ScriptingJsonSerializationSection.MaxJsonLength Property)

Basically, the "internal" JavaScriptSerializer respects the value of maxJsonLength when called from a web method; direct use of a JavaScriptSerializer (or use via an MVC action-method/Controller) does not respect the maxJsonLength property, at least not from the systemWebExtensions.scripting.webServices.jsonSerialization section of web.config. In particular, the Controller.Json() method does not respect the configuration setting!

As a workaround, you can do the following within your Controller (or anywhere really):

var serializer = new JavaScriptSerializer();

// For simplicity just use Int32's max value.
// You could always read the value from the config section mentioned above.
serializer.MaxJsonLength = Int32.MaxValue;

var resultData = new { Value = "foo", Text = "var" };
var result = new ContentResult{
    Content = serializer.Serialize(resultData),
    ContentType = "application/json"
};
return result;

This answer is my interpretation of this asp.net forum answer.

Excerpt answered 26/8, 2011 at 16:4 Comment(9)
Great solution! The web.config wasn't working for me either using asp.net mvc 2Cleavland
Wow, seems like an oversight on Microsoft's part to not make the Json() method respect the web.config settings for serialization length. Thanks for the answer this worked like a charm!Soche
If you're using MVC4 please see @fanisch answer as well.Muskogee
this answer is really helpful, it works. The one marked as answer, just setting the config maxJson size doesnt work for me.Sharpeyed
What is weird is that it seems as though Request.CreateResponse (which returns an HttpResponseMessage) of the ApiController, has a higher limit. Does anyone know what it is or why?Boatsman
How about Deserialization? I met this error at action's model binding.Buie
Was banging my head on the wall all this time because I was trying the web.config option. Since I was working on webservice only one liner helped me which is assigning the Int32.Maxvalue to the JavascriptSerializer(). Thanks a lotBrazzaville
I have problem with return Json(data) too. But workaround is simpler: var jsonResult = Json(res); jsonResult.MaxJsonLength = int.MaxValue; return jsonResult;Quickel
JsonResult is a real thing though. You're going to confuse people.Fifth
W
384

In MVC 4 you can do:

protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult()
    {
        Data = data,
        ContentType = contentType,
        ContentEncoding = contentEncoding,
        JsonRequestBehavior = behavior,
        MaxJsonLength = Int32.MaxValue
    };
}

in your controller.

Addition:

For anyone puzzled by the parameters you need to specify, a call could look like this:

Json(
    new {
        field1 = true,
        field2 = "value"
        },
    "application/json",
    Encoding.UTF8,
    JsonRequestBehavior.AllowGet
);
Whither answered 5/9, 2012 at 10:3 Comment(16)
I can confirm that the above works like a charm in MVC 4, thank you fanisch.Muskogee
I can confirm as well. Putting this code inside a base controller is definitely the cleanest approach proposed.Weed
This also works by just adding "MaxJsonLength = Int32.MaxValue" to the individual action result. In case the change is not desired controller or project wide.Carlycarlye
Worked perfectly for me! I have a base class that all of my controllers derive from and I just added this to the base class.Squaw
I had this issue with the EasyQuery for ASP.net component from korzh.com when executing a query that returned a large dataset. Adding this method straight into the EasyQuery controller fixed the issue.Devereux
This is the best answer. The MaxJsonLength can be configured per controller.Coaster
@Amit: I haven't notice a page performance penalty and I don't think that the property has anything to do with that. IMHO performance is proportional to the JSON string you are returning. The larger the string the slower the response.Whither
I confirm that it works in MVC 5 as well. I also wonder why all the other solutions have such high vote rates when this one is the most logical one. It solves the problem completely especially when you have a custom base controller class.Acrocarpous
WARNING: this solution disables the compression (if requested) of the response. Add this filter on your action: #3802607Achondroplasia
@fanisch: Can we assign MaxJsonLength = Int64.MaxValue instead of MaxJsonLength = Int32.MaxValue?Billetdoux
@MusakkhirSayyed: MaxJsonLength is Int32 so no we can't assign Int64.MaxValueWhither
@Whither I have a problem: My web application sends an AJAX request from the Javascript to the Server. The object being sent is too big for the default value of the serializer and therefore System.Web.Script.Serialization.JavaScriptSerializer.Deserialize throws an exception before my Controller's method can even try to do what it's supposed to do. Furthermore, the method I'm trying to call simply returns void. Where would I put your snippet? The snippet I added from the Accepted Solution isn't working for me. Thanks.Flagpole
@Flagpole This snippet is for returning a large JSON string. In your case you need to send a large string, so this is not going to help you. See this SO question #18622606 . I think it might help you.Whither
@Whither Thanks for the response to a multi-year-old answer :) Unfortunately I've tried that, and all manner of other solutions in this page relating to the web.config file to no luck. Oh well.Flagpole
Please note that this answer from user @ fanisch worked for my MVC4 app, Thank you ! You can also add this code in your base controller :)Composer
I am using mvc 5 and my problem was "The length of the string exceeds the value set on the maxJsonLength property." it was 20.000 rows. I set MaxJsonLength to 2147483644 it was still not working but above code fixed it i dont know how but thanks:)Telmatelo
C
71

if you are still getting error after web.config setting like following:

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

    

I solved it by following:

   public ActionResult/JsonResult getData()
   {
      var jsonResult = Json(superlargedata, JsonRequestBehavior.AllowGet);
      jsonResult.MaxJsonLength = int.MaxValue;
      return jsonResult;
    }

I hope this should help.

Cutup answered 19/9, 2016 at 9:44 Comment(2)
Setting the maxJsonLength in the web.config is unnesseary, setting the jsonResult.MaxJsonLength should suffice (at least it did for me (MVC5))Warsle
Woow its working Thanks.Thermae
D
65

You can configure the max length for json requests in your web.config file:

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

The default value for maxJsonLength is 102400. For more details, see this MSDN page: http://msdn.microsoft.com/en-us/library/bb763183.aspx

Dispel answered 20/7, 2009 at 6:43 Comment(3)
What is the stored value in this integer representing? Is this some sort of count of character? I guess what I am asking is, why an integer is being used? Thanks!Folse
@Folse the number represents how many bytes can be used for the maxJsonLength. As M4N mentioned, 102400 is the default (100KB).Showily
this is not worked for me and i not used webservices.Gitagitel
S
45

I was having this problem in ASP.NET Web Forms. It was completely ignoring the web.config file settings so I did this:

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        serializer.MaxJsonLength = Int32.MaxValue; 

        return serializer.Serialize(response);

Of course overall this is terrible practice. If you are sending this much data in a web service call you should look at a different approach.

Shadow answered 20/8, 2014 at 19:34 Comment(9)
did this work for you? where did you place this code?Rotl
Our problem was because we had a textarea that allowed for HTML and people were embedding images as HTML which caused the entry to become very large and JSON serializer to fail. I guess if it can be done users will do it...Beane
Please describe where we should put this code... @ShadowBanquer
@KorayDurudogan - I put this in the Ajax method that was returning the response, so in my controller. Hope that helps!Shadow
I am not challenging your response, but trying to get a better idea of what better approaches there are. I have a query that depending on what the user's criteria is will determine the result size. I return a JsonResult, Would it matter if I returned an excel file?Folse
@Folse - Depending on what you are trying to send back, would it be possible to send your data in smaller chunks and then assemble it all together once its finished? For example, let's say you are sending back 10,000 records. Could you send chunks of say 2,000 records until all 10,000 were sent. Perhaps think of things like that.Shadow
Thanks @Shadow for the response! Actually that's a good example, because a new requirement came in for a max of 10k records :) I will look into sending data back in sections.Folse
@Folse - That's awesome! :) If you don't end up sending it back in chunks, please do share how you ultimately do it! I'd like to know myself if you find a better way!Shadow
@Shadow I would like to send it back in chunks, but I have to figure out how to do that first! Lol. Here is a link to the question if you would like to contribute: #42936376Folse
B
36

I followed vestigal's answer and got to this solution:

When I needed to post a large json to an action in a controller, I would get the famous "Error during deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.\r\nParameter name: input value provider".

What I did is create a new ValueProviderFactory, LargeJsonValueProviderFactory, and set the MaxJsonLength = Int32.MaxValue in the GetDeserializedObject method

public sealed class LargeJsonValueProviderFactory : ValueProviderFactory
{
private static void AddToBackingStore(LargeJsonValueProviderFactory.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)
            LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);
    }
    else
    {
        IList list = value as IList;
        if (list != null)
        {
            for (int index = 0; index < list.Count; ++index)
                LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.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);
}

/// <summary>Returns a JSON value-provider object for the specified controller context.</summary>
/// <returns>A JSON value-provider object for the specified controller context.</returns>
/// <param name="controllerContext">The controller context.</param>
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
    if (controllerContext == null)
        throw new ArgumentNullException("controllerContext");
    object deserializedObject = LargeJsonValueProviderFactory.GetDeserializedObject(controllerContext);
    if (deserializedObject == null)
        return (IValueProvider) null;
    Dictionary<string, object> dictionary = new Dictionary<string, object>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase);
    LargeJsonValueProviderFactory.AddToBackingStore(new LargeJsonValueProviderFactory.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 = LargeJsonValueProviderFactory.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 > LargeJsonValueProviderFactory.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;
     }
  }
}

Then, in the Application_Start method from Global.asax.cs, replace the ValueProviderFactory with the new one:

protected void Application_Start()
{
    ...

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

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

    var largeJsonValueProviderFactory = new LargeJsonValueProviderFactory();
    ValueProviderFactories.Factories.Add(largeJsonValueProviderFactory);
}
Beaumont answered 10/1, 2017 at 17:51 Comment(2)
I did every thing i can, only your answer saved my day, this should have been accepted answerTourist
With this code we are able to override MVC controller max json Deserializetion limit of 4 mb, but is there a way to override web-api controller max json Deserializetion limitTourist
G
24

I fixed it.

//your Json data here
string json_object="........";
JavaScriptSerializer jsJson = new JavaScriptSerializer();
jsJson.MaxJsonLength = 2147483644;
MyClass obj = jsJson.Deserialize<MyClass>(json_object);

It works very well.

Gentle answered 18/10, 2011 at 13:27 Comment(2)
Awesome! This is the only solution that worked for me and its better anyways since its not a global change. Thanks!Epifocal
jsJson.MaxJsonLength = 2147483644; worked for me in a windows forms applicationBop
B
17

if, after implementing the above addition into your web.config, you get an “Unrecognized configuration section system.web.extensions.” error then try adding this to your web.config in the <ConfigSections> section:

            <sectionGroup name="system.web.extensions" type="System.Web.Extensions">
              <sectionGroup name="scripting" type="System.Web.Extensions">
                    <sectionGroup name="webServices" type="System.Web.Extensions">
                          <section name="jsonSerialization" type="System.Web.Extensions"/>
                    </sectionGroup>
              </sectionGroup>
        </sectionGroup>
Boykin answered 12/1, 2011 at 0:17 Comment(3)
I was having this problem. However, this answer did not work for me. Instead of adding the <sectionGroup> element described here, I just moved the whole newly added <system.web.extensions> block to the very end of my web.config... right before </configuration>. Then it worked.Robbins
This helped, but in my situation I needed to change your fourth line to <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>, as seen on this page: forums.asp.net/t/1446510.aspx/1Consolatory
@ClearCloud8 Get that comment spread across this page immediately.Tow
S
16

Simply set MaxJsonLength proprty in MVC's Action method

JsonResult json= Json(classObject, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
Strutting answered 3/4, 2017 at 11:7 Comment(0)
H
13

you can write this line into Controller

json.MaxJsonLength = 2147483644;

you can also write this line into web.config

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

`

To be on the safe side, use both.

Hogback answered 1/7, 2015 at 6:30 Comment(1)
you are missing a slash 2147483647"/>Illfavored
B
13

Fix for ASP.NET MVC if you want to fix it only for particular action that is causing the problem then change this code:

public JsonResult GetBigJson()
{
    var someBigObject = GetBigObject();
    return Json(someBigObject);
}

to this:

public JsonResult GetBigJson()
{
    var someBigObject = GetBigObject();
    return new JsonResult()
    {
        Data = someBigObject,
        JsonRequestBehavior = JsonRequestBehavior.DenyGet,
        MaxJsonLength = int.MaxValue
    };
}

And the functionality should be same, you can just return bigger JSON as response.


Explanation based on ASP.NET MVC source code: you can check what Controller.Json method does in ASP.NET MVC source code

protected internal JsonResult Json(object data)
{
    return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
}

It is calling other Controller.Json method:

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult
    {
        Data = data,
        ContentType = contentType,
        ContentEncoding = contentEncoding,
        JsonRequestBehavior = behavior
    };
}

where passed contentType and contentEncoding object are null. So basically calling return Json(object) in controller is equivalent to calling return new JsonResult { Data = object, JsonRequestBehavior = sonRequestBehavior.DenyGet }. You can use second form and parameterize JsonResult.

So what happens when you set MaxJsonLength property (by default it's null)? It's passed down to JavaScriptSerializer.MaxJsonLength property and then JavaScriptSerializer.Serialize method is called :

JavaScriptSerializer serializer = new JavaScriptSerializer();
if (MaxJsonLength.HasValue)
{
    serializer.MaxJsonLength = MaxJsonLength.Value;
}

if (RecursionLimit.HasValue)
{
    serializer.RecursionLimit = RecursionLimit.Value;
}

response.Write(serializer.Serialize(Data));

And when you don't set MaxJsonLenght property of serializer then it takes default value which is just 2MB.

Bish answered 30/12, 2019 at 23:59 Comment(1)
Thx! the first option save some time =DGossip
M
10

If you are getting this error from the MiniProfiler in MVC then you can increase the value by setting the property MiniProfiler.Settings.MaxJsonResponseSize to the desired value. By default, this tool seems to ignore the value set in config.

MiniProfiler.Settings.MaxJsonResponseSize = 104857600;

Courtesy mvc-mini-profiler.

Mada answered 29/7, 2013 at 12:8 Comment(0)
B
10

I suggest setting it to Int32.MaxValue.

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
Billowy answered 20/9, 2016 at 2:24 Comment(1)
int is an alias of Int32Plasterboard
S
9

How about some attribute magic?

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class MaxJsonSizeAttribute : ActionFilterAttribute
{
    // Default: 10 MB worth of one byte chars
    private int maxLength = 10 * 1024 * 1024;

    public int MaxLength
    {
        set
        {
            if (value < 0) throw new ArgumentOutOfRangeException("value", "Value must be at least 0.");

            maxLength = value;
        }
        get { return maxLength; }
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        JsonResult json = filterContext.Result as JsonResult;
        if (json != null)
        {
            if (maxLength == 0)
            {
                json.MaxJsonLength = int.MaxValue;
            }
            else
            {
                json.MaxJsonLength = maxLength;
            }
        }
    }
}

Then you could either apply it globally using the global filter configuration or controller/action-wise.

Southeaster answered 17/1, 2017 at 12:28 Comment(2)
Great answer. Nice use of custom attributes. Wondering if there is a specific (technical) reason that you set the default to 10 MB worth of one byte chars instead of the Max (int.MaxValue)?Bodhisattva
@Bodhisattva No, there wasn't any special reason for that.Anarchism
A
5

If you are encountering this sort of issue in View, you can use below method to resolve that. Here Iused Newtonsoft package .

@using Newtonsoft.Json
<script type="text/javascript">
    var partData = @Html.Raw(JsonConvert.SerializeObject(ViewBag.Part));
</script>
Aguila answered 25/3, 2017 at 10:59 Comment(2)
Does this mean I don't have to worry about max length if I use Json.NET? I don't think there is a way to set max length in Json.NET so I'm hoping it just works out of the box.Aggri
Excellent Answer thank you! This also worked when I was attempting to load an object.Evaporite
C
5

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:

<add key="aspnet:MaxJsonLength" value="20971520" />

and then create the two following classes

public class JsonValueProviderConfig
{
    public static void Config(ValueProviderFactoryCollection factories)
    {
        var jsonProviderFactory = factories.OfType<JsonValueProviderFactory>().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
{

    /// <summary>Returns a JSON value-provider object for the specified controller context.</summary>
    /// <returns>A JSON value-provider object for the specified controller context.</returns>
    /// <param name="controllerContext">The controller context.</param>
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        if (controllerContext == null)
            throw new ArgumentNullException("controllerContext");

        object deserializedObject = CustomJsonValueProviderFactory.GetDeserializedObject(controllerContext);
        if (deserializedObject == null)
            return null;

        Dictionary<string, object> strs = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
        CustomJsonValueProviderFactory.AddToBackingStore(new CustomJsonValueProviderFactory.EntryLimitedDictionary(strs), string.Empty, deserializedObject);

        return new DictionaryValueProvider<object>(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<string, object> strs = value as IDictionary<string, object>;
        if (strs != null)
        {
            foreach (KeyValuePair<string, object> 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<string, object> _innerDictionary;

        private int _itemCount;

        static EntryLimitedDictionary()
        {
            _maximumDepth = CustomJsonValueProviderFactory.GetMaximumDepth();
        }

        public EntryLimitedDictionary(IDictionary<string, object> 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;
    }
}
Crystallization answered 3/6, 2018 at 11:13 Comment(1)
Thanks it's working ... Thanks a lot @Maxim GershkovichEpstein
T
4

The question really is whether you really need to return 17k records? How are you planning to handle all the data in the browser? The users are not going to scroll through 17000 rows anyway.

A better approach is to retrieve only a "top few" records and load more as required.

Toweling answered 20/7, 2009 at 6:44 Comment(3)
The default list from json will give 17k records. But the autocomplete feature will list only the records that matches the characters that the user types, thus it wont need to scroll the list more. SO what i need is to set unlimited length for maxJsonLength which can serialize the 17k data.Mcmillen
You could use a combination of server and client side filtering. It could be hard to filter all the data on the client side, not to mention the network latency.Toweling
Having arrived at this same issue a while back, I chose to implement an "onsearch" handler for the autocomplete, and have the web service call pass the "search" text and do a Top10 query using the search criteria as a filter. This meant more individual ajax requests, that just getting the full list on page load, but it also meant that all the requests/responses were much smaller.Cleistogamy
C
4

For those who are having issues with in MVC3 with JSON that's automatically being deserialized for a model binder and is too large, here is a solution.

  1. Copy the code for the JsonValueProviderFactory class from the MVC3 source code into a new class.
  2. Add a line to change the maximum JSON length before the object is deserialized.
  3. Replace the JsonValueProviderFactory class with your new, modified class.

Thanks to http://blog.naver.com/techshare/100145191355 and https://gist.github.com/DalSoft/1588818 for pointing me in the right direction for how to do this. The last link on the first site contains full source code for the solution.

Colman answered 11/7, 2013 at 17:37 Comment(0)
B
3

You can set it in the config as others have said, or you can set in on an individual instance of the serializer like:

var js = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
Bondage answered 27/6, 2013 at 20:10 Comment(0)
R
3
 JsonResult result = Json(r);
 result.MaxJsonLength = Int32.MaxValue;
 result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
 return result;
Roderickroderigo answered 16/9, 2019 at 6:36 Comment(0)
A
2

It appears that there is no "unlimited" value. The default is 2097152 characters, which is equivalent to 4 MB of Unicode string data.

As as already been observed, 17,000 records are hard to use well in the browser. If you are presenting an aggregate view it may be much more efficient to do the aggregation on the server and transfer only a summary in the browser. For example, consider a file system brower, we only see the top of the tree, then emit further requestes as we drill down. The number of records returned in each request is comparatively small. A tree view presentation can work well for large result sets.

Appalachian answered 20/7, 2009 at 6:51 Comment(1)
rather bizarrely the default in code (new JavaScriptSerializer()).MaxJsonLength is 2097152 bytes but the web service ResponseFormatJson is the 102400 bytes unless explicitly set.Being
R
2

Just ran into this. I'm getting over 6,000 records. Just decided I'd just do some paging. As in, I accept a page number in my MVC JsonResult endpoint, which is defaulted to 0 so it's not necessary, like so:

public JsonResult MyObjects(int pageNumber = 0)

Then instead of saying:

return Json(_repository.MyObjects.ToList(), JsonRequestBehavior.AllowGet);

I say:

return Json(_repository.MyObjects.OrderBy(obj => obj.ID).Skip(1000 * pageNumber).Take(1000).ToList(), JsonRequestBehavior.AllowGet);

It's very simple. Then, in JavaScript, instead of this:

function myAJAXCallback(items) {
    // Do stuff here
}

I instead say:

var pageNumber = 0;
function myAJAXCallback(items) {
    if(items.length == 1000)
        // Call same endpoint but add this to the end: '?pageNumber=' + ++pageNumber
    }
    // Do stuff here
}

And append your records to whatever you were doing with them in the first place. Or just wait until all the calls finish and cobble the results together.

Rosol answered 12/7, 2013 at 22:33 Comment(0)
S
2

I solved the problem adding this code:

String confString = HttpContext.Current.Request.ApplicationPath.ToString();
Configuration conf = WebConfigurationManager.OpenWebConfiguration(confString);
ScriptingJsonSerializationSection section = (ScriptingJsonSerializationSection)conf.GetSection("system.web.extensions/scripting/webServices/jsonSerialization");
section.MaxJsonLength = 6553600;
conf.Save();
Sprig answered 20/11, 2014 at 11:57 Comment(1)
This seems like a hackish solution but interesting approach regardless. I found it useful thanks! For me in apsnet mvc 5 controller I had to remove 'Current' from the namespace. I made a couple adjustments: string confString = HttpContext.Request.ApplicationPath.ToString(); var conf = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(confString); var section = (System.Web.Configuration.ScriptingJsonSerializationSection)conf.GetSection("system.web.extensions/scripting/webServices/jsonSerialization"); section.MaxJsonLength = int.MaxValue; conf.Save();Ghassan
T
2

We don't need any server side changes. you can fix this only modify by web.config file This helped for me. try this out

<appSettings>
 <add key="aspnet:MaxJsonDeserializerMembers" value="2147483647" />
<add key="aspnet:UpdatePanelMaxScriptLength" value="2147483647" />
</appSettings>  

and   

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

Thoroughfare answered 11/8, 2017 at 4:19 Comment(0)
R
1

Solution for WebForms UpdatePanel:

Add a setting to Web.config:

<configuration>
  <appSettings>
    <add key="aspnet:UpdatePanelMaxScriptLength" value="2147483647" />
  </appSettings>
</configuration>

https://support.microsoft.com/en-us/kb/981884

ScriptRegistrationManager class contains following code:

// Serialize the attributes to JSON and write them out
JavaScriptSerializer serializer = new JavaScriptSerializer();

// Dev10# 877767 - Allow configurable UpdatePanel script block length
// The default is JavaScriptSerializer.DefaultMaxJsonLength
if (AppSettings.UpdatePanelMaxScriptLength > 0) {
    serializer.MaxJsonLength = AppSettings.UpdatePanelMaxScriptLength;
}  

string attrText = serializer.Serialize(attrs);
Reenter answered 14/4, 2016 at 5:15 Comment(0)
A
1

i use this and it worked for Kendo grid read request.

{ 
  //something
   var result = XResult.ToList().ToDataSourceResult(request);
   var rs = Json(result, JsonRequestBehavior.AllowGet);
   rs.MaxJsonLength = int.MaxValue;
   return rs;
}
Artemisa answered 4/9, 2021 at 18:20 Comment(0)
I
0

use lib\Newtonsoft.Json.dll

public string serializeObj(dynamic json) {        
    return JsonConvert.SerializeObject(json);
}
Isom answered 1/12, 2015 at 13:8 Comment(0)
N
-2

if this maxJsonLength value is a int then how big is its int 32bit/64bit/16bit.... i just want to be sure whats the maximum value i can set as my maxJsonLength

<scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
        </webServices>
    </scripting>
Nicobarese answered 19/10, 2016 at 11:47 Comment(0)
A
-5

You do not need to do with web.config You can use short property during catch value of the passing list For example declare a model like

public class BookModel
    {
        public decimal id { get; set; }  // 1 

        public string BN { get; set; } // 2 Book Name

        public string BC { get; set; } // 3 Bar Code Number

        public string BE { get; set; } // 4 Edition Name

        public string BAL { get; set; } // 5 Academic Level

        public string BCAT { get; set; } // 6 Category
}

here i use short proporties like BC =barcode BE=book edition and so on

Aenneea answered 3/4, 2018 at 12:53 Comment(1)
This won't help if the bulk of the data is in the property valuesSheronsherourd

© 2022 - 2024 — McMap. All rights reserved.