For .NET developers, the Microsoft Windows Communication Foundation (WCF) is an excellent resource for creating service-based Web applications. Defining web services is relatively easy using WCF; using Visual Studio .NET, you can set up a solution with the interfaces needed for WCF quickly and easily. Actually doing the communication using Ajax, however, requires a client-side component to make and handle the various Ajax calls. Almost all of the examples on the Intertubes(™) use jQuery, but that’s not the only JavaScript toolkit on the market. How would you accomplish these goals if you were developing your service-based applications using the Dojo Toolkit?

It turns out that consuming WCF-based services with Dojo is quite easy to do, and in this post we’ll show you how to do it. For reference, we’ll be using this article from Sridhar Subramanian at C# Corner which shows how to write your WCF-based services, so we won’t be going into the details of the C# component here. Instead, we’ll focus on the client-side code.

Get the code

If you’d like to see this in action, download this zip archive, which is set up as a solution using Microsoft Visual Web Developer 2010 Express. The HTML file we’ll be using for examples is called “WCFWithDojo.html”, which you’ll notice is a pure HTML file and not an ASP.NET page. To see how the actual Ajax calls are made with Dojo, scroll to the bottom of that file.

Calling the web services

The first example in this file calls an old-style ASMX-based web service, with the result expected as JSON. Most of the default web services in .NET expect HTTP POST-style calls, which is represented in the Dojo Toolkit with dojo.xhrPost. Here’s the basic example:

dojo.xhrPost({
	url: "/service/CountryProvinceWebService.asmx/GetProvince",
	handleAs: "json",
	contentType: "application/json",
	postData: dojo.toJson({ "Country": "USA" }),
	load: function(result){
		//	The result here is of type Object; use JS accessors 
		//	to extract information from it.
	},
	error: function(err){
		console.warn(err);
	}
});

This is the basic signature of any of Dojo’s XHR methods (xhrGet, xhrPost, xhrPut and xhrDelete); you call the method by passing it an object that defines the parameters of a call. Dojo’s XHR methods implement Promises as well, but for the purpose of this post we’ll keep to this particular format. Let’s break down the parameters of this call.

url

The URL of the service to be called. In this case, we’re looking to get a list of Provinces for a country.

handleAs

How to interpret the content type of the response. Typical values are “text”, “xml”, “json”; see the Dojo API for all of the possible options.

contentType

What the content type of the post body is. The services in this blog post are mostly written to expect JSON in the body of the HTTP post, so we set the contentType accordingly.

postData

The actual contents of the post body. The services in this post were mostly written to expect a raw JSON string, so we set that here.

Finally, the load and error functions are the callback definitions that may be executed once the service returns a response. The error function handles any errors—including any errors that may have occurred during the execution of the load method.

The load method is where the bulk of the callback work is done. Normally you will define it with a single argument, which is the contents of the response from the service, “pre-interpreted” to be the right content type that you define in the “handleAs” parameter, in this case a JSON-based Javascript object. In addition, there is an optional second argument (typically called “args”) that is a reference to an object that defined all the parameters of the call, including an “xhr” member that is a direct reference to the XMLHTTPRequest object used to make the call (in case you need to inspect something like the raw responseText or look at content headers returned). In our load methods in the example solution, all we are doing is taking the JSON object returned and formatting it for display in the browser, but obviously you would be using it to do any of the web application work you need to.

Let’s take a look at the same call, but defined on the server using WCF:

dojo.xhrPost({
	url: "/service/CountryProvinceWCFService.svc/GetProvince",
	handleAs: "json",
	contentType: "application/json",
	postData: dojo.toJson({ "Country": "USA" }),
	load: function(result){
		//	The result here is of type Object; use JS accessors 
		//	to extract information from it.
	},
	error: function(err){
		console.warn(err);
	}
});

You’ll notice that the primary changes here are the URL signature (the url parameter) and, if you are running the examples, a slight change in the format of the returned JSON object. Otherwise, nothing has really changed at all; you are still making an HTTP POST, you’re still setting the body of the post to be a JSON string, and you’re still handling the result as a JSON object.

Not all web applications are using JSON as the transport format; many use XML. Here’s an example of calling the same WCF service, but expecting XML back as the response instead:

dojo.xhrPost({
	url: "/service/CountryProvinceWCFService.svc/GetProvinceXML",
	handleAs: "xml",
	contentType: "application/json",
	postData: dojo.toJson({ "Country": "USA" }),
	load: function(result){
		//	The result here is of type XMLDocument; use typical XML DOM methods 
		//	to extract information from it.
	},
	error: function(err){
		console.warn(err);
	}
});

(A side note; the actual running example taps into the second argument passed to the load method to get at the XML as raw text.)

You’ll note two basic differences: the handleAs parameter is now “xml”, and the URL signature changed slightly. This is due to the way the services were defined (see the aforementioned article at C# Corner). Otherwise, this call is exactly the same as the other three examples.

What if you have a service method that expects more than one parameter? In this case, there is simple way of passing the parameters–simply add the parameters to the postData object. For example:

dojo.xhrPost({
	url: "/service/CountryProvinceWCFService.svc/GetProvinceAndBrowser",
	handleAs: "json",
	contentType: "application/json",
	postData: dojo.toJson({ "Country": "USA", "Browser": "" }),
	load: function(result){
		//	The result here is of type Object; use JS accessors 
		//	to extract information from it.
	},
	error: function(err){
		console.warn(err);
	}
});

I left the “Browser” parameter of the postData blank for the purposes of this example, but it would trivial to accept data from the user interface to post back to the server.

If your service methods are designed to respond to an HTTP GET, you’d simply use the xhrGet version of Dojo’s Ajax methods, like so:

dojo.xhrGet({
	url: "/service/CountryProvinceWCFService.svc/GetProvinceGET",
	handleAs: "json",
	content: { Country: "USA" },
	load: function(result){
		//	The result here is of type Object; use JS accessors 
		//	to extract information from it.
	},
	error: function(err){
		console.warn(err);
	}
});

Note that two things have changed: using dojo.xhrGet as opposed to xhrPost, and changing the parameter “postData” to “content”. When doing normal Ajax calls with the Dojo Toolkit, “content” is usually the parameter used because Dojo has special handling to take care of that content depending on what type of HTTP verb you are using. However, since most of the services in our WCF code expects JSON in a particular way, we need to use the postData parameter instead. Note also that since we’ve moved to a GET request, we no longer need to specify the contentType of our data (since it is passed to the server using the query string).

Finally, if you have set up your WCF service methods as RESTful, Dojo can handle that as well:

dojo.xhrGet({
	url: "/service/CountryProvinceWCFService.svc/GetProvinceREST/USA",
	handleAs: "json",
	load: function(result){
		//	The result here is of type Object; use JS accessors 
		//	to extract information from it.
	},
	error: function(err){
		console.warn(err);
	}
});

Note that here, our URL signature has changed so that we are passing our parameters as part of the URL string.

As you can see, consuming .NET WCF-based services using the Dojo Toolkit is straightforward. For more information about using Dojo’s Ajax methods, see the Dojo Reference Guide, as well as the API definitions at dojotoolkit.org (all of Dojo’s XHR-based Ajax methods are prefixed with “xhr”).