Getting "The JSON request was too large to be deserialized"
asp.net Mvcknockout.jsasp.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
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.