Getting "The JSON request was too large to be deserialized"

asp.net Mvcknockout.js

asp.net Mvc Problem Overview


I'm getting this Error:

> The JSON request was too large to be deserialized.

Here's a scenario where this occurs. I have a class of country which hold a list of shipping ports of that country

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Port> Ports { get; set; }
}

I use KnockoutJS on the client side to make a cascading drop downs. So we have an array of two drop downs, where the first one is country, and the second one is ports of that country.

Everything is working fine so far, this my client side script:

var k1 = k1 || {};
$(document).ready(function () {

    k1.MarketInfoItem = function (removeable) {
        var self = this;
        self.CountryOfLoadingId = ko.observable();
        self.PortOfLoadingId = ko.observable();
        self.CountryOfDestinationId = ko.observable();
        self.PortOfDestinationId = ko.observable();  
    };

    k1.viewModel = function () {
        var marketInfoItems = ko.observableArray([]),
            countries = ko.observableArray([]),
            
			saveMarketInfo = function () {
                var jsonData = ko.toJSON(marketInfoItems);
                $.ajax({
                    url: 'SaveMarketInfos',
                    type: "POST",
                    data: jsonData,
                    datatype: "json",
                    contentType: "application/json charset=utf-8",
                    success: function (data) {
                        if (data) {
                            window.location.href = "Fin";
                        } else {
                            alert("Can not save your market information now!");
                        }

                    },
                    error: function (data) { alert("Can not save your contacts now!"); }
                });
            },
		     
            loadData = function () {
                $.getJSON('../api/ListService/GetCountriesWithPorts', function (data) {
                    countries(data);
                });
            };
        return {
            MarketInfoItems: marketInfoItems,
            Countries: countries,
            LoadData: loadData,
            SaveMarketInfo: saveMarketInfo,
        };
    } (); 

The problem occurs when a country like China is selected, which has lots of ports. So if you have 3 or 4 times "China" in your array and I want to send it to the server to save. The error occurs.

What should I do to remedy this?

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

You have to adjust the maxJsonLength property to a higher value in web.config to resolve the issue.

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

Set a higher value for aspnet:MaxJsonDeserializerMembers in the appSettings:

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

If those options are not working you could try creating a custom json value provider factory using JSON.NET as specified in this thread.

Solution 2 - asp.net Mvc

If you don't want to change a global setting in the web config

Using a global setting will activate large json responses throughout your entire application which might open you up to a denial of service attack.

If a few choice locations are allowed this, you can very quickly use another json serialiser using the Content method like so:

using Newtonsoft.Json;

// ...

public ActionResult BigOldJsonResponse() 
{
    var response = ServiceWhichProducesLargeObject();
    return Content(JsonConvert.SerializeObject(response));
}
// ...

Solution 3 - asp.net Mvc

Setting doesn't always work. The best way to handle this is through the controller, You would have to write your own Serialize JSON method. This is how I solved returning a very large json serialized object as a response to a jquery .Ajax call.

C#: replace the JsonResult data type with ContentResult

// GET: Manifest/GetVendorServiceStagingRecords
[HttpGet]
public ContentResult GetVendorServiceStagingRecords(int? customerProfileId, int? locationId, int? vendorId, DateTime? invoiceDate, int? transactionId, int? transactionLineId)
{
    try
    {
        var result = Manifest.GetVendorServiceStagingRecords(customerProfileId, locationId, vendorId, invoiceDate, null, null, transactionId, transactionLineId);
        return SerializeJSON(result);
    }
    catch (Exception ex)
    {
        Log.Error("Could not get the vendor service staging records.", ex);

        throw;
    }
}

private ContentResult  SerializeJSON(object toSerialize)
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    serializer.MaxJsonLength = Int32.MaxValue; // Wahtever max length you want here
    var resultData = toSerialize; //Whatever value you are serializing
    ContentResult result = new ContentResult();
    result.Content = serializer.Serialize(resultData);
    result.ContentType = "application/json";
    return result;
}

Then in Web.config file increase to maximum size

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

That work for me.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKayvan KarimView Question on Stackoverflow
Solution 1 - asp.net MvcVJAIView Answer on Stackoverflow
Solution 2 - asp.net MvcspeciesUnknownView Answer on Stackoverflow
Solution 3 - asp.net MvcMauricio SolórzanoView Answer on Stackoverflow