Thursday, September 10, 2009

Passing Server Side Objects to the Client Side Using JSON

It is often a requirement of a web based application (using any framework) to pass values from the server side to the client side so they can be consumed by Javascript code.

One solution to this is to use hidden input fields and set the value of these on the server side. This does have the advantage that if the value is changed on the client side, it will be passed back to the server, but if this is not a desired effect, it adds bloat to the parameters that are posted to the server. It is also quite inefficient in terms of page size and doesn't handle complex objects without considerable pain.

Enter JSON! The ASP MVC framework provides a very neat class called the JavaScriptSerializer that will serializes objects into JSON. Given the following class:

public class ClassToSerialize
{
    public string SomeString { get; set; }
    public int SomeInt { get; set; }
}

the following call:

new JavaScriptSerializer().Serialize(new ClassToSerialize { SomeString = "Test string", SomeInt = 13 })

returns the following string:

{"SomeString":"Test string","SomeInt":13}

We just need to assign this value to a variable in Javascript and we can access the properties. I use a small helper function to do this for us in our MVC view:

public static class JsonHelper
{
    public static string RenderObject(this ViewPage view, string objectName, object value)
    {
        return string.Format("", objectName, new JavaScriptSerializer().Serialize(value));
    }
}

Using this function from our view:

<%= this.RenderObject("SerializedClass", new ClassToSerialize { SomeString = "Test string", SomeInt = 13 }) %>

allows us to access the object properties in Javascript, such as SerializedClass.SomeString and SerializedClass.SomeInt. I have a couple of overloads of the helper function that allow the caller to choose whether or not to render the script tags and variable declaration, allowing us to embed the object in an existing script block and to assign the value to an already declared variable.