A bit about the stuff I've done

Monday, 22 October 2012

Solving long JSON return from a webservice

I was being plagued by this error intermittently:
Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property

Some Googling led me to realise that there is indeed a limit, and this limit is quite low.
Most of the posts explained how to increase the limit but also explained why this was a bad idea and that you should instead reduce your JSON size.

I agree with this, better to return what you can to the client and tell them to "try again" for whatever is left.
But this poses a problem - how do you know how much data you can return at once?
Google drew a blank on this one.

This little function here will do the trick:

using System.Configuration; using System.Web.Configuration; public int GetMaxJSONLength() { Configuration cConfig = WebConfigurationManager.OpenWebConfiguration(null); return ((ScriptingWebServicesSectionGroup) cConfig. SectionGroups["system.web.extensions"]. SectionGroups["scripting"]. SectionGroups["webServices"] ).JsonSerialization.MaxJsonLength; }
This can be executed from anywhere, it doesn't have to be part of the web project itself.

Something else to be aware of - any strings in your return value will be encoded.
That means characters like < and > will become \u003c and \u003e - 6 times longer than they were previously.
So if you have a string containing html this can make a substantial difference to the length of the string.

To account for this make sure you use the length of the encoded string, not the original.

Tuesday, 9 October 2012

The woes of inline functions

OK; so I like inline fucntions really - especially in javascript. But now I am realising their evil intent after I spent a not insubstantial amount of time tracing a bug.
here is the scenario:
A simple method with tbh not a whole lot in it.
In fact the entire method is taken by a single if/else block. Regardless of the outcome of both if blocks it is necassary to call a method afterwards.
So obviously that call goes outside the if.
Normally that would be fine.
But in my case the else block contained an inline function used as a callback.
A callback that will occur some undetermined (but very small) amount of time after the if block has exited.
Of course I needed to wait until this callback had been executed before calling the final method.
function DoSomething() { if (condition) { DoOneThing(); } else { AsyncronuslyDoAnother(function (result){ DoSomethingWithTheResultWhenTheAsyncCallCompletes(); }); } DoFinalThing(); } Now the simple solution in this instance was to move the call to DoFinalThing() to be inside the if block, and also inside the anonymous callback function.
function DoSomething2() { if (condition) { DoOneThing(); DoFinalThing(); } else { AsyncronuslyDoAnother(function (result){ DoSomethingWithTheResultWhenTheAsyncCallCompletes(); DoFinalThing(); }); } } However in my case the problem only arose in the first place because I simply didn't notice the inline function when I added the call to DoFinalThing() and assumed that it was all just part of the else logic.
So additionally I removed the inline function and henceforth declare all such things to be evil!
(ok well not quite, but at least I am more wary now!)
function AsyncCallback(result) { DoSomethingWithTheResultWhenTheAsyncCallCompletes(); DoFinalThing(); } function DoSomething3() { if (condition) { DoOneThing(); DoFinalThing(); } else { AsyncronuslyDoAnother(AsyncCallback); //N.B. no parens on AsyncCallback - we are passing a reference to the method not invoking it } }