TIL: Why "__type" is added when I serialize to JSON

In my recent work adding features to a mature ASP.NET Web Forms application using AngularJS, I've made much use of the [WebMethod] attribute. Using [WebMethod], we can expose endpoints in the code-behind of an ASPX page and invoke them via the AngularJS $http service.

As you might imagine, we've created many data transfer objects (DTO) used to move data between the client and server. When a [WebMethod] returns one of these entities, the .Net JavaScriptSerializer class handles generating a JSON representation of the entity being returned to the client. Going the other direction, the JavaScriptSerializer also deserializes entity instances used as arguments to a [WebMethod].

The JavaScriptSerializer automatically adds a __type property to any object with a public constructor it serializes to JSON.

Given the following data transfer class:

namespace Company.Web.Entities.DataTransfer
    public class DocumentTransferObject
        public DocumentTransferObject()
            ID = 0;
            Title = "";

        public int ID{ get; set; }
        public string Title{ get; set; }

The JSON generated would be:

    __type:  'Company.Web.Entities.DataTransfer.DataTransferObject', 
    ID: 77,
    Title: 'My Document'

You may have noticed that the __type property accounts for more than 50% of the characters in the serialized object instance. Surely it's unnecessary, right?

Well, maybe.

The JavaScriptSerializer uses the __type property during the deserialization process to determine what server side type should be created. This is very important if you're interested in sending the object from the client back to the server.

If you're like me, though, you have quite a few DTOs that are one-way server-to-client only. In this case, that __type property is adding an awful lot of unnecessary bloat.

It must be configurable.

You'd think so, right? At the absolute worst, a custom serializer could be registered with the JavaScriptSerializer instance.

ASP.NET WebForms does not (as far as I know) provide access to the instance of the JavaScriptSerializer that's performing the serialization for us. As such, there's no opportunity to configure or otherwise manipulate the serialization process.

We must be able to work around it.

Yes, thankfully, we can work around it. You may recall that the __type property is generated when serializing an instance of a class that has a public constructor. So, if we can eliminate the public constructor, we can eliminate the __type property.

If the DTO's constructor is made internal (and, in case a public creation interface is required, a static factory method is added), like so:

namespace Company.Web.Entities.DataTransfer
    public class DocumentTransferObject
        public static DocumentTransferObject()
            return new DocumentTransferObject();

        internal DocumentTransferObject()
            ID = 0;
            Title = "";

        public int ID{ get; set; }
        public string Title{ get; set; }

The JSON generated now becomes:

    ID: 77,
    Title: 'My Document'

Note that this technique is only appropriate for those types that are only ever returned from [WebMethod]s. Without a public constructor, it would be impossible for the JavaScriptSerializer to deserialize into the type (since it can't create one). The JavaScriptSerializer is smart enough to know this, so it omits the __type property.

Packt Pub: Learning Bing Maps API has been published!

Learning Bing Maps API Cover

I had the distinct pleasure of acting as a Technical Reviewer for the recently-published Packt Publishing title Learning Bing Maps API.

The author, Artan Sinani, quickly brings the reader up to speed on topics such as consuming data from the Bing Maps spatial data API, hosting a Bing Map in a webpage via the AJAX control, and extending the AJAX control to provide custom functionality.

Artan's writing style is clear and concise and he covers each topic thoroughly.

I enjoyed assisting Artan and the publishing team at Packt, and I'm sure you'll enjoy the book as well.

Debouncing JavaScript

What is Debouncing?

'Debouncing' translates a set of repeating events, each occuring within a certain duration from the previous, into a single event.

I was originally introduced to the term when creating a hardware device with a physical button. The user of the device expected a single press of the button to trigger a single event in the device. Electrically, though, buttons - especially cheap buttons - generate tens or hundreds of 'press' events each time they're pressed.

To the user, this electrical 'bouncing' is problematic. If not accounted for, the device would have generated tens or hundreds of repeated events, rendering it completely unusable.

To alleviate the problem, the electrical engineer I was working with connected the button to the microcontroller running the device through a debounce circuit. The circuit noted the arrival time of the the first and each subsequent 'press' event from the button, and waited until some number of milliseconds after the last event to alert the microcontroller that the button had been pressed, and thus the bouncing press events from the button were translated into a single event for the device to process.

How Does Deboucing Apply to Software?

I'm working on an AngularJS application that processes window resize events to ensure that some of the elements on the screen are sized optimally for the current viewport.

Chrome (I love Chrome) emits a single window resize event each time the user stops resizing the window. Internet Explorer 10 (I hate IE), on the other hand, continuously emits window resize events while the user is resizing the window.

Some of the elements that the app resizes when the window resize require some significant processing (grids containing potentially hundreds of cells), and I certainly didn't want the elements continuously resizing in IE while the user changes the window size.

What I really wanted to do was debounce the resize event so that the application code only fires once each time the user completes resizing the window.

Enter Underscore.js

The wonderful underscore library providesdebounce(func, wait, immediate) that according to the documentation:

Returns a function, that, as long as it continues to be invoked, will not be triggered. The function will be called after it stops being called for N milliseconds. If immediate is passed, trigger the function on the leading edge, instead of the trailing.

Quick Example

var invocations = 0;

var functionToDebounce = function(){  

var debouncedFunction = _.debounce(functionToDebounce, 100);

for(var i = 0; i < 100; i++){  

}, 250);

The function functionToDebounce increments the the invocations variable each time it is called. We've provided functionToDebounce to underscore's debounce function, and subsequently called the debounced version of the function 100 times in a tight loop.

100ms after the last time debouncedFunction() is called, functionToDebounce will finally be called just once. When the alert is displayed, it will contain the number 1.

Tying in AngularJS

For my application that needed to process browser resize events, a directive that debounced the window.resize event and broadcast a message to other directives via the $rootScope solved the problem nicely.

Here's a (very simple) version of the directive:

    .directive('resizeDebouncer', ['$rootScope', '$window', function($rootScope, $window){
        return {
         restrict: 'A',
        link: function(scope, element, attr){
            var onResize = function(){

            var debouncedResize = _.debounce(onResize, 100);

            // use jQuery to bind the debouncedResize
            // function to the window.resize event
            $($window).on('resize', debouncedResize);

Other directives may then subscribe to the window.debouncedResize event broadcast by $rootScope to react to browser window size changes.

In an upcoming post we'll expand on the resizeDebouncer directive, and also refactor it so that its easily unit-testable.

Error Retrieving Polygon Geometry Using the ArcGIS Server SOAP API

Using the following code snippet, I’m able to retrieve the geometry of a feature without fail 99.9% of the time.

QueryFilter Filter = new QueryFilter();
Filter.WhereClause = "GLOBALID='global-id-here'";
Filter.SubFields = "SHAPE";
RecordSet records = ServiceProxy.QueryFeatureData("MyMap",0, Filter);

Certain polygons, though, cause the XML Deserializer to throw a fit:

System.InvalidOperationException: There is an error in XML document (1, 6544). ---> System.InvalidOperationException: The specified type is abstract: name='Point',     namespace='http://www.esri.com/schemas/ArcGIS/9.3', at .
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read11_Point(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read26_CircularArc(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read25_Segment(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read12_Ring(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read20_PolygonN(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read1_Object(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read158_Record(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read159_RecordSet(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMapServerProxy.Read188_QueryFeatureDataResponse()
   at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer51.Deserialize(XmlSerializationReader reader)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   --- End of inner exception stack trace ---

The error always occurs when serializing a Point within a CircularArc. I haven’t been able to determine if all Polygons with a CircularArc segment cause the problem, or if only CircularArcs with some particular characteristic are troublesome.

I’ve encountered the error in multiple datasets from multiple organizations, so it doesn’t appear to be dependent upon the source. I’ve also verified that it occurs in ArcGIS Server 10.0 as well as 9.3.1 (I was hoping that it was something that would be fixed by the 10.0 release)

Executing the equivalent query for the same asset using the REST API works properly.

Has anyone else encountered this?