Tuesday, February 03, 2009

Consuming Services from Client Side JavaScript (Part II)

In the previous post we discussed how we can call server side web/WCF services from JavaScript. in this post we will discuss how we can use Java Script Object Notation (JSON) to send/receive objects between client side JavaScript and server side services

JSON

JSON is a text based, human readable, platform independent data exchange format. it’s build on JavaScript object notations which allows you to define an object as a list of members and values that are enclosed in curly braces ({}), each member is delimited by a comma. Within each member, the name and value are delimited by a colon (:). the following example shows how you can define the object Car

<script type="text/javascript">
function DisplayCarInfo()
{
var car= {
"Name": "Mondeo",
"Model": 2009,
"Maker": "Ford",
"Drivetrains": "RWD"
};
alert(car.Name);
alert(car.Maker);
alert(car.Model);
alert(car.Drivetrains);
}
</script>


we can also express complex object hierarchies

<script type="text/javascript">
function DisplayCarInfo()
{
var car= {
"Name": "Mondeo",
"Model": 2009,
"Maker": "Ford",
"Drivetrains": "RWD",
"Options" :
[
{
"OptionName" : "ABS",
"OptionValue" : true
}
,
{
"OptionName" : "FogLights",
"OptionValue" : false
}
]
};

alert(car.Name);
alert(car.Maker);
alert(car.Model);
alert(car.Drivetrains);
for (i=0;i<car.Options.length;i++)
{
alert(car.Options[i].OptionName+":"+car.Options[i].OptionValue);
}
}
</script>

JSON and .NET

The .Net framework 3.5 includes classes (such as DataContractJsonSerializer and JavaScriptSerializer) that support the serialization/deserialization of objects to/from JSON representation.

The following console application shows how to get the JSON representation of an object

using System;
using System.Web.Script.Serialization ;

namespace JSONTest
{
class Car
{
public string Name { get; set; }
public string Model { get; set; }
public int Year { get; set; }
}
class Program
{
static void Main(string[] args)
{
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
Car obj = new Car() { Name = "Ford", Model = "Mondeo", Year = 2009 };
Console.WriteLine(jsSerializer.Serialize(obj));
}
}
}

Scott Guthrie has a nice post that shows how to create an extension method to convert every object to its JSON representation

JSON and WCF

Windows Communication Foundation has a built in support for creating services that can be consumed from JavaScript and send/receive data in JSON format. a service must expose an end point configured with the webHttpBinding, this binding uses HTTP requests that use plain old XML messages or JSON instead of SOAP based messaging, you will use the enableWebScript behavior to set the default data format for the service to JSON instead of XML.

let’s consider the following basic service that contains a method that returns a complex data type


using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Web.Script.Services;

namespace WCFJSONService
{
[ServiceContract(Namespace = "WCFJSONService")]
public interface ICarsInfoService
{
[OperationContract()]
Car GetCarInfo(string carName);
}

[DataContract]
public class Car
{
[DataMember]
public string Name{get;set;}
[DataMember]
public string Maker{get;set;}
[DataMember]
public int Model { get; set; }
[DataMember]
public CarOption[] Options { get; set; }
}
[DataContract]
public class CarOption
{
[DataMember]
public string OptionName { get; set; }
[DataMember]
public string OptionValue { get; set; }
}

[ScriptService]
public class CarsInfoService : ICarsInfoService
{
public Car GetCarInfo(string carName)
{
switch (carName)
{
case "Corolla":
return new Car()
{
Maker="Toyota", Model=2009, Name="Corolla",
Options=new CarOption[]
{
new CarOption(){ OptionName="ABS",OptionValue="Yes"},
new CarOption(){ OptionName="FogLights",OptionValue="Yes"},
}
};
case "Sunny":
return new Car()
{
Maker = "Nissan",
Model = 2009,
Name = "Sunny",
Options = new CarOption[]
{
new CarOption(){ OptionName="ABS",OptionValue="Yes"},
new CarOption(){ OptionName="FogLights",OptionValue="No"},
}
};
default:
return null;
}
}
}
}


To use the service from client side JavaScript we need to configure the service using the following configuration
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="WCFJSONService.CarsInfoServiceBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="WCFJSONService.CarsInfoService">
<endpoint address=""
behaviorConfiguration="WCFJSONService.CarsInfoServiceBehavior"
binding="webHttpBinding"
contract="WCFJSONService.ICarsInfoService"/>
</service>
</services>
</system.serviceModel>

we will use the service from JavaScript as follows

<!--default.aspx-->
<asp:ScriptManager runat="server" ID="scriptManageR">
<Services>
<asp:ServiceReference Path="~/CarsInfoService.svc" />
</Services>
</asp:ScriptManager>
<select id="lstCar">
<option value="Corolla">Corolla</option>
<option value="Sunny">Sunny</option>
</select>
<input type="button" value="click" onclick="javascript:CallWCFService();" />
<script type="text/javascript">
function CallWCFService() {
var service = new WCFJSONService.ICarsInfoService();
var lst = $get('lstCar');
var car = service.GetCarInfo(lst.value,OnSucceeded);

}
function OnSucceeded(car) {
if (car != null) {
alert("Car Name:" + car.Name);
alert("Car Model:" + car.Model);
alert("Car Maker:" + car.Maker);
for (i = 0; i < car.Options.length; i++)
{
alert(car.Options[i].OptionName + ":" + car.Options[i].OptionValue);
}
}
}
</script>

as you can see the result returned from the service is automatically converted to JSON representation, if you want to see the actual JSON data returned follow these steps:

- Add the WebGet attribute to the GetCarInfo method, this will allow us to access the service method using the HTTP get verb

[OperationContract()]
[WebGet()]
Car GetCarInfo(string carName);

- Browse to the following URL http://youhostname:portNumber/CarsInfoService.svc/getCarInfo?carName=Corolla , you will be prompted to download a file, save the file and open it using the Notepad you will find the JSON representation of the Car object

For more info i suggest the following MSDN links:

WCF Web Programming Model Overview

Creating WCF Services for ASP.NET AJAX

Download the sample code from here:

No comments: