To read the article online, visit http://www.4GuysFromRolla.com/articles/040809-1.aspx

Building Interactive User Interfaces with Microsoft ASP.NET AJAX: A Look at JSON Serialization

By Scott Mitchell


Introduction


Web applications commonly exchange information between the client (the browser) and the server (the ASP.NET application). In traditional web applications, this communication is usually insinuated when the visitor submits a form. This prompts the browser to re-request the page, sending the values of the form's inputs through the HTTP POST header. The server then renders the page and returns the entire page's markup, which is then redisplayed. AJAX-enabled web applications streamline this process. Instead of synchronous, bulky postbacks, AJAX-enabled applications use JavaScript to asynchronously communicate with the web server, transmitting only the necessary data and intelligently updating only the part of the screen whose contents have been modified (rather than redrawing the entire page, as with a full page postback).

Transmitting information over the Internet requires the sender to serialize it into some string-based format prior to sending it, and the receiver to deserialize it back into an object state that it can work with. For instance, if the client wants to send an array of integers to the server it must convert that array from its in-memory representation into a string, so that it can be transmitted across the network. Likewise, upon receiving the request, the receiver must turn that string representation of an array of integers back into an array of integers, so that it can use it programmatically.

XML was designed to serialize complex data into a string-based format, and early AJAX frameworks used XML as the serialization format. However, modern AJAX implementations use an alternate serialization format known as JavaScript Object Notation, or JSON. Like XML, JSON is an open, text-based serialization format, that is both human-readable and platform independent. It differs from XML in three important ways: it is much simpler to understand and implement than XML; it is less verbose, resulting in a slimmer payload; and, most importantly, data serialized in JSON can intuitively be parsed by JavaScript. In other words, working with data formatted in JSON in JavaScript involves one line of code - there's no need for a separate deserialization library or custom code to parse a message.

This article provides an overview of JSON's rules and illustrates how it is used in AJAX-enabled web applications. We'll also look at using the Microsoft ASP.NET AJAX framework's JavaScriptSerializer class, which facilitates serializing and deserializing JSON-formatted messages on the client in JavaScript or in C# or Visual Basic code on the server. Read on to learn more!

An Overview of Literal Notation


Programming languages often include some syntax for defining a literal, or fixed value in code. For example, in C# or Visual Basic you can express the literal value of a number by simply typing it; to express the literal value of a string you surround the text by quotation marks. The following code snippet shows assigning the literal value of "Hello, World!" and 3.14159 to string and decimal variables in C# and Visual Basic, respectively.

// C#
string message = "Hello, World!";


' VB
Dim pi As Decimal = 3.14159

The characters "Hello, World!" and 3.14159 that appear in the above code are examples of literals.

In the past, C# and Visual Basic had a rather limited set of literals. There were strings, numbers, Boolean values, and arrays, for instance. Over the years, these languages have been enhanced to include support for additional literals. Visual Basic 9 added support for XML literals and object initializers. C# 3.0 also supports object initializers, as well as collection initializers. Visual Basic and C#'s object initializers allow objects to be defined literally. The following snippet, taken from An Extensive Examination of LINQ: Extension Methods, Implicitly Typed Variables, and Object Initializers, shows C# and VB code that creates a new Employee object by literally defining the object's properties and values:

// C#
Employee emp = new Employee
    {
       EmployeeID = 1,
       Name = "Scott",
       Salary = 75000M,
       ...
    };


' VB
Dim emp As New Employee With { _
         .EmployeeID = 1, _
         .Name = "Scott", _
         .Salary = 75000, _
         ...
       }

The literal syntax differs based on the literal and the programming language, although most languages use the same syntax for primitive literals like numbers, strings, and Boolean values. As the example above shows, the syntax for C#'s object initializers encompasses the property values within curly braces that appear right after the class name (Employee, in this case). Each class property/value pair appears within the curly braces and the value/pair are delimited by an equals sign. The property/value pairs are delimited from one another via a comma. In VB, the With keyword denotes the start of the object initializer. Like with C#, the property/value pairs are placed within curly braces and are delimited from one another with commas. However, each property name must be prefixed with a period.

JavaScript's Literal Notation


JavaScript has long offered rich literal support. There is, of course, literal support for simple types (numbers, strings, etc.) as well as for regular expressions. There is also literal notation for complex types like arrays and objects. For instance, arrays can be denoted literally with square brackets and a comma-delimited list of values, as the following JavaScript code snippet illustrates.

var Fibonacci = [ 1, 1, 2, 3, 5, 8, 13 ];

Objects can also be defined literally using the following syntax:

var emp =
   {
      "EmployeeID": 1,
      "Name": "Scott",
      "Salary": 75000,
      "Certifications": [ "MCSD", "CCNP", "MCP" ],
      ...
   }

JavaScript's literal object notation looks similar to C#'s object initializer syntax, namely a set of properties encased in curly braces with each property/value pair delimited from one another by a comma. The main difference is that the property names (EmployeeID, Name, etc.) are encased in quotation marks and the property and value are delimited from one another via a colon (rather than an equals sign). (Actually, according to the JavaScript spec the quotes around the property names are optional. However, the JSON standard, as we'll not shortly, requires that the property names of object's be quoted.)

Also note that the object literal notation is not limited to simple types. The emp object defined above has a property named Certifications that is an array. Likewise, the literal arrays notation can contain complex types; you could literally define an array of objects, where each object was literally defined.

Enter JSON...


JSON, or JavaScript Object Notation, is a data-exchange format based on JavaScript's literal object notation. JSON's syntactic rules are more strict than JavaScript's, but are quite similar and quite simple. What's more, JSON is an amazingly simple standard that can be summarized in one sentence and exhaustively and formally described in a paragraph. Here's the one-line overview:
JSON-formatted messages are composed of a single, top-level object or array, which itself can hold objects, arrays, strings, numbers, Boolean values, or the value null.
An object is an unordered set of name/value pairs and is denoted using a subset of JavaScript's literal object notation, and follows the rules we just discussed in the previous section (namely, that the name/value pairs are encased in curly braces, the name is in quotes, name/value pairs are delimited by commas, and the name and value are delimited by a colon). Arrays are an ordered collection of values encased within square brackets and with each name/value pair delimited by a comma. Strings are text encased in quotation marks; numbers are the digits that make up the number; the two Boolean values are the tokens true and false; and the null value is the token null.

That's it!

JSON in AJAX-Enabled Web Applications


JSON is the preferred serialization format for AJAX-enabled web applications for a number of reasons. For starters, it's much simpler than XML. There are built-in data types, no confusing namespaces, strict yet simple rules for formatting, and native object and array support. Granted, this simplicity does not allow for the breadth of features and uses that XML's complexity affords, but this simplicity does make it easier to implement and use JSON.

Second, JSON will always result in a slimmer payload than XML, as it encodes data with fewer characters. A web application that shuttles fewer bytes over the Internet will appear snappier and more interactive than one that uses heavier payloads.

Finally, and most importantly, creating and parsing JSON messages in JavaScript is much easier than creating and parsing XML messages. With XML-formatted payloads, some work must be done to map the assorted XML elements into objects, arrays, and properties. For example, imagine that an AJAX-enabled web application used JavaScript to make out-of-band calls to the server to get information about employees. The client might send in the querystring the EmployeeID value, while the server would respond with a payload that includes the requested employee's information. If that payload was XML-formatted, the response from the server for a particular employee might look like the following:

<Employee EmployeeID="1">
   <Name>Scott</Name>
   <Salary>75000</Salary>
   <Certifications>
      <Certification>MCSD</Certification>
      <Certification>CCNP</Certification>
      <Certification>MCP</Certification>
   </Certifications>
</Employee>

Upon receipt of this payload, the JavaScript on the page would need to parse the XML and extract the data into a JavaScript object with properties for the EmployeeID, Name, Salary, and Certifications values. This would involve writing JavaScript code that would enumerate the elements in the XML payload and would likely take anywhere from 5-25 lines of code.

If the web server responded with a JSON-formatted payload, things would be much simpler. Instead of the above XML payload, the server could respond with the following JSON message:

{
   "EmployeeID": 1,
   "Name": "Scott",
   "Salary": 75000,
   "Certifications": [ "MCSD", "CCNP", "MCP" ]
}

Because the returned payload is already valid JavaScript code, it can be "parsed" and assigned to a variable using JavaScript's eval function like so:

var emp = eval( jsonString );

Where jsonString is the contents of the JSON message returned from the server. After executing the above line of code the variable emp is assigned to the object denoted by the JSON message! It now has the properties EmployeeID, Name, Salary, and Certifications at its disposal. For example, you could display the employee's name and salary using the following JavaScript:

alert("Employee " + emp.Name + " makes " + emp.Salary + " per year!");

(In actuality, AJAX frameworks do not use the eval function to parse JSON messages, but instead use their own approach that first verifies that the JSON message does not include any potentially dangerous script.)

Writing the JavaScript code to serialize a value into a JSON message requires a bit more code, but it's not terribly complicated and is certainly much simpler than the code needed to generate a corresponding XML representation.

For more information on JSON's formatting rules refer to the JSON.org website. For a more detailed comparison between JSON and XML, read An Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET, written by Atif Aziz and myself.

JSON In Action


The previous installment in this article series, Retrieving Server-Side Data Using Web Services, looked at how to create script services using Microsoft's ASP.NET AJAX Framework. Script services are Web Services that are enhanced to allow for data to be serialized via JSON rather than via SOAP and XML. The Retrieving Server-Side Data Using Web Services article included a demo of a script service named NorthwindServices that, among other things, had a method named AnswerQuickSummaryReportQuery that would return the number of products in the database that matched a certain criteria, such as, "How many products cost less than $5.00?" or, "How many products cost exactly $15.00?"

The NorthwindServices script service was called from an ASP.NET page whenever the user clicked a particular button on the page. Clicking that button executed JavaScript code that used a client-side proxy class to call the script service. This proxy class was automatically created for us by the ASP.NET AJAX framework. The proxy class makes an HTTP request to the script service, passing the input parameters as a JSON message and receiving back a JSON message as response. Using Fiddler or any other HTTP traffic analyzing tool, you can inspect the content sent by the proxy class to the script service and see the response.

Calling the NorthwindServices and asking how many products cost less than $15 sends the following JSON message to the script service:

{"operation":"CostLess","queryCost":"15.00"}

This is a JSON message. There's a top-level object that contains two properties, operation and queryCost, with string values of "CostLess" and "15.00". The NorthwindServices script service takes these values, deserializes them and passed them into the AnswerQuickSummaryReportQuery method. This method then queries the database to get the number of products that meet this criteria. This count is returned by the AnswerQuickSummaryReportQuery method. The script service serializes the return value into the following JSON message, which is sent back to the client as the response.

{"d":24}

This value is received by the proxy class and parsed, at which point it can be used by your JavaScript code.

The following diagram illustrates this workflow.

The script service data-exchange workflow.

For more information on using Fiddler to examine HTTP traffic be sure to check out Troubleshooting Website Problems by Examining the HTTP Traffic.

Generating and Parsing JSON Messages


When using script services in an AJAX-enabled ASP.NET application, the ASP.NET AJAX framework automatically handles generating and parsing the JSON messages sent between the client and server. There may be times when you want to create or parse JSON messages yourself, either in JavaScript or in server-side code. For example, the AJAX Control Toolkit is an open-source collection of AJAX-enabled Web controls for ASP.NET websites. Many of these controls use script services to communicate with the server. These controls expect script services with a pre-defined method signature; that is, they expect the script service method they are configured to use to accept a specific number of input parameters and return a value of a specific type. In cases where you, the page developer, may need to supply additional information in the script service call, the script service signature will offer an additional string input parameter into which you can pass any input. If you need to pass a single additional input parameter you can do so through this extra parameter. If you need to pass two or more additional input parameters then you'll need to serialize them into a string representation, pass them in this single input parameter, and then deserialize them in the script service. In such a case, you can serialize the additional input parameters using JSON.

The Microsoft ASP.NET AJAX Framework includes both client- and server-side mechanisms for creating and parsing JSON messages. To create or parse JSON messages in C# or VB code, use the JavaScriptSerializer class, which is found in the System.Web.Script.Serialization namespace. To create or parse JSON messages in JavaScript, use the Sys.Serialization.JavaScriptSerializer class, which is part of the ASP.NET AJAX framework's client-side API.

The demo available for download at the end of this article includes examples of using both the server- and client-side JSON serialization implementations in the ASP.NET AJAX Framework. Specifically, the demo pages illustrate using the AutoComplete control from the AJAX Control Toolkit. The AutoComplete control adds auto-complete support to textboxes in a web page, providing a list of possible matches based on the characters the user has already entered into the textbox. The control calls a script service that you specify, passing it the text the user has entered and expecting back a string array of possible matches, which is then displays in a list beneath the textbox. This script service may optionally include a string contextKey input parameter for any additional information needed.

The demo I created has the user select one or more categories from a series of checkboxes. The AutoComplete then only lists possible product matches based on the selected categories. For this to work, we need to pass in the set of selected category IDs into the script service. But all we have at our disposal is that single contextKey input parameter. The solution is to serialize the array of category IDs into a JSON message and pass that message as the contextKey input parameter. This involves serializing the array of category IDs into a JSON message and then deserializing it from a string back into an array of category IDs in the C# or Visual Basic script service code.

The download includes two demos that show how to do the serialization: JsonSerializationOnServer.aspx, which serializes the array in C# and Visual Basic code; and JsonSerializationOnClient.aspx, which serializes the array in JavaScript code using the ASP.NET AJAX framework's client-side API. I'll let you explore the download to see exactly how things work, but here's a snippet of how the serialization takes place on the server (it's quite easy):

// C#
JavaScriptSerializer json = new JavaScriptSerializer();
string jsonMessage = json.Serialize(arrayOfCategoryIDs);


' VB
Dim json As New JavaScriptSerializer()
Dim jsonMessage As String = json.Serialize(arrayOfCategoryIDs)

Simply create an instance of the JavaScriptSerializer class and call its Serialize method, passing in the object to serialize. The resulting string returned by the method is the JSON message corresponding to the passed-in object.

Likewise, deserializing the JSON message into an object is a straightforward task with the JavaScriptSerializer class. The following code snippet is from the AutoComplete.asmx script service; the code below deserializes the passed-in JSON message into an array of integers (the selected category ID values).

// C#
JavaScriptSerializer json = new JavaScriptSerializer();
List<int> categories = null;
if (jsonMessage != null)
   categories = json.Deserialize<List<int>>(jsonMessage);


' VB
Dim json As New JavaScriptSerializer()
Dim categories As List(Of String) = Nothing
If jsonMessage IsNot Nothing Then
   categories = json.Deserialize(Of List(Of String))(jsonMessage)
End If

Conclusion


JSON is a simple data-exchange format that produces lightweight, human-readable messages that can be easily created and parsed via JavaScript code (as well as by other languages via frameworks or libraries, such as the ASP.NET AJAX Framework). JSON messages are the most common mechanism by which information is exchanged in AJAX-enabled web applications. Microsoft's ASP.NET AJAX Framework uses JSON-formatted messages for its script services. Furthermore, it provides both client- and server-side mechanisms for creating and parsing JSON messages programmatically.

Happy Programming!

  • By Scott Mitchell


    Attachments:


  • Download the Demo Code Used in this Article

    Further Reading


  • An Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET
  • JSON.org - Introducing JSON
  • JavaScriptSerializer Class (server-side technical docs)
  • Sys.Serialization.JavaScriptSerializer Class (client-side technical docs)
  • Article Information
    Article Title: ASP.NET.Building Interactive User Interfaces with Microsoft ASP.NET AJAX: A Look at JSON Serialization
    Article Author: Scott Mitchell
    Published Date: April 8, 2009
    Article URL: http://www.4GuysFromRolla.com/articles/040809-1.aspx


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers