Today I was calling a web service from an Ajax client in an application that I'm working on and I noticed that I wasn't getting any results. To get a better idea of what was going on, I wired up the error handler for the web service call and did some tracing to see the error message. The error handling code that I added looked like this:
var msg = String.format(
"Stack trace: {0}\nService Error: {0}\nMessage: {1}\nStatus Code: {2}\nException Type: {3}\nTimed out: {4}",
error.get_stackTrace(),
error.get_message(),
error.get_statusCode(),
error.get_exceptionType(),
error.get_timedOut()
);
Sys.Debug.trace(msg);
I re-ran the application and this is the exception that was getting returned:
Stack trace: at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal...
Message: Specified cast is not valid.
Status Code: 500
Exception Type: System.InvalidCastException
Timed out: false
The exception was telling me that there was a serialization problem with the Type being returned from the web service call. This was interesting to me because I had just changed the return Type of the ws method call. I initially wondered whether there was some generated JS type that was cached and that the new Type that I was returning was different from it. That seemed unlikely though so I looked at the members on the new Type that I was returning. There was a Guid, an Int32, a custom Enum, and a string. Hrmm. I decided to remove the Enum property from the Type to see whether it was causing the failure, and sure enough, my application ran fine. Here's the Enum that I was using:
public enum PinType : short {
Standard = 0,
Favourite = 1,
}
Next I added the enum based property back but I changed the enum so that it was a standard Int32-based one. Again, it ran fine... so the problem is obviously that the built in JavaScriptSerializer cannot handle short's. In my case I just decided to cut my losses and leave my enum inheriting from Int32, but here's an article that describes a bit about how to implement your own custom Json serializer to use with non-supported Types:
http://www.asp.net/ajax/documentation/live/mref/T_System_Web_Script_Serialization_JavaScriptConverter.aspx
When you have written your custom converter you can either add it programatically or via the web configuration file like so:
<jsonSerialization maxJsonLength="500">
<converters>
<add name="MyConverter"
type="MarkItUp.CustomEnumTypeConverter"/>
</converters>
</jsonSerialization>