William Duffy

Glasgow Based C# ASP.NET Web Developer

JSON serialization in ASP.NET

When working with JavaScript and ASP.NET together you will no doubt find yourself having to return objects from the server side domain to the client side domain.

One common method of doing this is to return XML which represents the object you wish to return. You then map the values in the XML document to your JavaScript object (or parse the XML document manually) at which point you can start working with it as normal.

However, a much easier option is to return JSON (JavaScript Object Notation). Using a framework such as jQuery you can simply retrieve the JSON and have concrete JavaScript object ready for manipulation.

This is highly advantageous when you are performing AJAX operations. For example, imagine you have a server-side postcode query system that returns latitude/longitude values for a submitted postcode. After the postcode is queried on the server a Location object is created which holds the latitude/longitude values to return to the client. This object would look like the following…

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Location
{
    public Location(string postcode, double latitude, double longitude)
    {
        Postcode = postcode;
        Latitude = latitude;
        Longitude = longitude;
    }
 
    public string Postcode { get; set; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

To allow the client to receive the Location object we create an HttpHandler. In a production environment this HttpHandler would query your database for the submitted postcode. However in the example below we will use a mock object to demonstrate JSON serialization in action. (Serialization is simply a means of representing an object in state. In this case the state will be text for transmission over the http protocol.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Web;
using System.Web.Script.Serialization;
 
public class LocationHandler : IHttpHandler {
 
    public void ProcessRequest (HttpContext context) {
 
        string postcode = context.Request.QueryString["postcode"];
 
        // This is where you would query your database
        // i.e. Assess postcode for valid data
        // i.e  Create postcode database parameter @postcode
        // i.e. SELECT latitude, longitude FROM tblGeocodes WHERE postcode = @postcode;"
        // However for this demo we will create a mock object
 
        double rnd = new Random().NextDouble();
        Location loc = new Location(postcode, 55.95254 * rnd, -4.767455 * rnd);
 
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        context.Response.Write(serializer.Serialize(loc));
        context.Response.ContentType = "application/json";
 
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }
 
}

The code above creates the Location object. It then creates a JavaScriptSerializer object which it uses to serialize the Location object to the response stream. The result is a JSON representation of the Location object that can be sent to the client where JavaScript can recreate it. The JSON looks as follows

{"Postcode":"pa16 8ng","Latitude":14.566054759251575,"Longitude":-1.24110559757015}

Note: You will need to ensure that you have a reference to the System.Web.Extensions dll. If you are using ASP.NET 3.5 this is already installed and available. If you are using ASP.NET 2.0 you will need to download ASP.NET AJAX.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>JSON Location</title>
    <script src="jquery-1.3.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $().ready(function() {
            $('#<%=txtPostcode.ClientID%>').keyup(function() {
                $.getJSON("LocationHandler.ashx", { postcode: this.value }, function(location) {                   
                    $(".postcode").text(location.Postcode);
                    $(".latitude").text(location.Latitude);
                    $(".longitude").text(location.Longitude);
                });
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
 
    Get location for postcode: 
    <asp:TextBox ID="txtPostcode" MaxLength="8" runat="server" /><br /><br />
 
    Postcode: <span class="postcode"></span><br />
    Latitude: <span class="latitude"></span><br />
    Longitude: <span class="longitude"></span>
 
    </form>
</body>
</html>

I am using jQuery to perform the AJAX request, but you can use whatever javascript method/framework you prefer.

IMPORTANT

Retreiveing and working with JSON is perfectly safe to do when you know and trust the source. However, if you do not know the source that is serving the JSON this can be a potentially dangerous call. So in cases where you are not in full control or fully trust the JSON provider you should seek a different solution.


Categorized as Uncategorized

5 Comments

  1. Great article. Something I use A LOT these days due to clients want more interation, speed and websites to run like desktop apps.

    One thing I noticed with the JavaScriptSerializer was dates. Instead of using a bit more thought Microsoft have the Serializer turn dates into the UTC format but with \Date()\ wrapping the number, making it hard to use in javascript without having to do a replace each time.

    1 option is to create an extra property on your object that returns your dates as strings, so the serializer works. However that gets messy.

    Another solution is:

    String.prototype.parseDate = function() {

    var m = this.match(/^\/Date\((\d+)\)\/$/);
    var date = null;
    if (m)
    date = new Date(parseInt(m[1]));

    return date.toLocaleDateString();
    }

    add that to the top of your javascript file and you can then do:

    json.DateCreated.parseDate()

    which will display the date correctly with little fuss, but not getting away from parsing all your dates. However sending dates back to the Deserializer is another problem!

    Cheers

  2. Neat code snippet Colin. I hadn’t run into the date problem before, purely due to luck I think. But at least now I’m ready for it! :)

  3. Great! I`m learning asp.net and I my code wasn`t working. Thank you a lot!

  4. This is an awesome, walk through. Thank you!

comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

Trackbacks & Pingbacks

  1. Colin Wiseman

    Great article. Something I use A LOT these days due to clients want more interation, speed and websites to run like desktop apps.

    One thing I noticed with the JavaScriptSerializer was dates. Instead of using a bit more thought Microsoft have the Serializer turn dates into the UTC format but with \Date()\ wrapping the number, making it hard to use in javascript without having to do a replace each time.

    1 option is to create an extra property on your object that returns your dates as strings, so the serializer works. However that gets messy.

    Another solution is:

    String.prototype.parseDate = function() {

    var m = this.match(/^\/Date\((\d+)\)\/$/);
    var date = null;
    if (m)
    date = new Date(parseInt(m[1]));

    return date.toLocaleDateString();
    }

    add that to the top of your javascript file and you can then do:

    json.DateCreated.parseDate()

    which will display the date correctly with little fuss, but not getting away from parsing all your dates. However sending dates back to the Deserializer is another problem!

    Cheers

  2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

    Trackbacks & Pingbacks

    1. William

      Neat code snippet Colin. I hadn’t run into the date problem before, purely due to luck I think. But at least now I’m ready for it! :)

    2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

      Trackbacks & Pingbacks

      1. Fulano

        Great! I`m learning asp.net and I my code wasn`t working. Thank you a lot!

      2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

        Trackbacks & Pingbacks

        1. Dwain

          This is an awesome, walk through. Thank you!

        2. comment_type == "trackback" || $comment->comment_type == "pingback" || ereg("", $comment->comment_content) || ereg("", $comment->comment_content)) { ?>

          Trackbacks & Pingbacks

          1. Najmul Hoda

          Leave a Reply