WCF AJAX-Friendly Services

October 30th, 2008

At one of my first jobs as web developer I worked with a friend, Gustavo Miranda, A.K.A Morph, we used PHP language. We maintained three websites at different datacenters, but the owner was the same (my friend’s uncle). At that time, one day, we had an integration request: one of the websites should show data stored at the others.

Right now it’s clear that the use web services is the best solution, but at that time, we were about seventeen years old and we had no idea about ajax or web services because they were not so popular.

So we started to think and research, and finally we found a solution: We had a PHP page that could return plain text, and to call it, we used a hidden IFRAME, and we use java script to read, parse and show the information.

Sometime later I learned about XML, so I started to create POX (Plain Old XML) “Services” (but I didn’t use to call them “POX services” ), and use the XmlHttpRequest object to make requests. After that, SOAP came, and, in my opinion, mistakenly called “Web” Services became popular.

Today, AJAX and Services are in their plenitude, Microsoft has his own AJAX framework, and the creation of services has never been so easy like using WCF.

In this post, I would like to show how easy it is to create & consume AJAX-friendly services combining the new WCF 3.5 service behaviors & bindings and the Microsoft AJAX framework.

Creating the Service

As creating any service, we should start by the contract. In this case, I will use a Meetings Request service. So these will be my DataContracts:

meetingRquestContract personContract

And this will be my ServiceContract:

serviceContract

As you can see I’m providing a Namespace to the ServiceContract attribute, this is important because this namespace will be the one that we will use from javascript. We will focus in the GetMeetingPage method, for demo proposes we will have only one MeetingRequest by page.

Once we have our contracts, let’s create the service; to do this, we will use the AJAX-enabled WCF Service Template:

template 

This will create a Meetings.svc file and its code behind Meetings.svc.cs, it will also create a section in the Web.config file to configure the service, so let’s go step by step.

MeetingsService.svc: The ServiceHost file. The important thing here is the Service property; this property specifies the type that will contain our service functionality.

 serviceHost

The first thing to do inside it is to clean up the service class, located at the code behind, and implement our ServiceContract, IMeetingsService, the result should be the next one:

 meetingsService

Note that the MeetingsService class implements our ServiceContract, IMeetingsService. To keep it simple, I’m using a static class named MeetingsStore to encapsulate the data access logic, just to get notice I’m using mockdata and LinqToObjects to retrieve it.

The next step is to configure our service. The goal of WCF is that we can configure our service through metadata.

To create SOAP services that work through HTTP, we commonly use bindings like basicHttpBinding or wsHttpBinding. But, as you know, negotiating with SOAP messages from javascript is pretty complex, so we need a binding that allow our enpoinds respond to HTTP requests instead of SOAP messages: the solution is the new webHttpBinding, available from WCF 3.5.

webConfig

As you can see in this Web.config screenshot, we set our binding as webHttpBinding, our contract and our behavior. Let’s stop a second in the behavior, as you can see we are using the enableWebScript behavior, this behavior is the one that makes the magic to allow us to consume our service from ASP.NET AJAX web pages, later we will see this in detail.

So, that’s all for our service, let’s consume it…

Consuming the service

To consume the service the first thing to do is create an AJAX-enabled aspx page, by using the “AJAX Web Form” template or just adding a ScriptManager component to any aspx page. If you use Master Pages, the ScriptManager component should be placed in the master page, and the content pages should use the ScriptManagerProxy component.

The first thing to do is to give to the ScriptManager a reference to our service, that’s what you can see in this screenshot:

jsservicereference 

If we run this page, it looks like nothing is happening, but if we research in the generated html code; we will find something like this:

source

What?? It looks like we are adding a javascript file reference, but instead of myLocalJsFile.js we have MeetingsService.svc/jsdebug. Do you remember the enableWebScript behavior? This is exactly it. If we copy & paste this reference in our browser, something will happen…

downladingthemagic

We used enableWebScript behavior in our service, this means that if we append /jsdebug or just /js to our service URI, it will return a file containing a javascript proxy to our service. If we save and open this file with Visual Studio we will see what it means:

jsproxy

As you can see, this file contains a JSON definition having the same methods that our service contract IMeetingsService, and in the first line we have a namespace registration, the same namespace that we defined in our ServiceContract. So, let’s back to our .aspx page and invoke the service.

To do this, we just have to create an instance of this proxy, in this case ajaxfriendly.services.IMeetingsService, and use its methods, and this task is especially easy using Visual Studio 2008, because we have javascript intellisense & debugging…

jsintellisense

To call any method we have to provide the service parameters and also, because this will run asynchronous, we have to provide one handler to succeededCallback event, and another to failedCallbackEvent. Finally we will have something like this…

js

In the succeededCallback event handler we just display the data. If we run and debug, we can see that in the “result” parameter we’ve our DataContract retrieved by our service in JSON.

An that’s all, the next is play with JavaScript, JQuery (recommended), to manage this data.

You can download the Code Here.

Regards!

Leave a Reply