Handling JsonMaxLength Exception on Deserializing Large Json Objects

Recently I was writing an application that needed to pass a substantial Json object. I had never run into any issues passing Json in .Net but the object I was now working with was pretty large.

My application pattern for this project is MVVM. I was using Dapper for my database objects and so far had found using the built-in JsonResult class perfect, up until I encountered the JsonMaxLength exception. This exception is caused because we tried to pass an object larger than the app thinks it can handle.

I have found a bunch of odd workarounds for this depending on what technologies are at work here. For exampl, the Telerik website says to reduce the string length you may try to make your grid page-able. Another idea out there was to write a custom factory to attempt to overwrite the maxJsonLength property.

The first example from Telerik is sad really because we should be able to get our data to the client. I’m working with the same technology as much bigger companies, albeit without the bells and whistles of VS Pro. The second example is just a headache for me. First of all, your factory may work in .Net 4 and not 4.5.  I also would rather not worry about my backend framework since I have the bigger issue of just getting the data to the client in the first place. Then there is the other point that I already have a tool capable of handling large strings and Json objects, and it’s already powering my client side anyway. JavaScript.

So how can I get a super big Json Object from the JsonResult successfully past this max length Json issue? Pass a string instead, stringify, parse and done.

Here is an example:

[HttpGet]
public string getBigJsonString()
{
    using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["database"].ConnectionString))
    {
        Object json = db.Query<fancyObject>("[dbo].[usp_GetFancyData]" commandType: CommandType.StoredProcedure).ToList();
        var serializer = new JavaScriptSerializer();
        //For simplicity just use Int32's max value.
        serializer.MaxJsonLength = Int32.MaxValue;
        var result = new ContentResult
        {
            Content = serializer.Serialize(json),
            ContentType = "application/json"
        };
        return result.Content;
    }
}

What I changed here was that instead of utilizing the JsonResult class, which will hit that limit of the sealed class that is packaged in VS, I can instead use the overrideable defaults of the string class. Now I can set it to the max of int, which is about 2 GB. I didn’t need to change my web.config, the app start or write any factories to do this. I simply changed my method to return a string.

Now if you were to just view this in the console you’ll see your data, but it’s a string and not usable in its current state. My application is angular and all my components are being fed by Json objects.

Over in the client side in my AngularJS app my http request looks like this:

$http({ method: 'GET', url: '/MyController/getBigJsonString' })
.success(function (data, status) {
    console.log($scope._strData); //you can view the raw striig here
    $scope._strData = JSON.stringify(data);
    $scope.data = JSON.parse($scope._strData);
    $scope.filteredData = $scope.data.slice(0, 20);
})
.error(function (data, status) {
    $scope.statusMessage = 'There was an error loading the data....Oops!';
});
//my pagination function
$scope.$watch('currentPage + numPerPage', function () {
    var begin = (($scope.currentPage - 1) * $scope.numPerPage)
        , end = begin + $scope.numPerPage;
    $scope.filteredData = $scope.data.slice(begin, end);
});

I included my pagination function just for completeness and to show that you can still paginate without going the Telerik route and snipping your data.

Like I said earlier, you don’t need to write custom chunks code that you can’t use later. JavaScript can already handle Json processing and manipulation, this solution would work no matter if you are using jQuery, Knockout, Angular of VanillaJS. The JSON.parse and JSON.stringify methods should be your friends.

 

A Web Developer by trade, find me on Github A motorcycle enthusiast at heart. Most days I'd rather be in the woods anywhere.