Accessing Server-Side Data from Client Script: Using WCF Services with jQuery and the ASP.NET Ajax Library
By Scott Mitchell
Introduction
Today's websites commonly exchange information between the browser and the web server using Ajax techniques - the browser executes JavaScript code typically in response to the page loading or some user action. This JavaScript makes an asynchronous HTTP request to the server. which then processes the request and, perhaps, returns data that the browser can then seamlessly integrate into the web page. Two earlier articles - Accessing JSON Data From an ASP.NET Page Using jQuery and Using Ajax Web Services, Script References, and jQuery, looked at using both jQuery and the ASP.NET Ajax Library on the browser to initiate an Ajax request and both ASP.NET pages and Ajax Web Services as the entities on the web server responsible for servicing such Ajax requests.
This article continues our examination of techniques for implementing lightweight Ajax scenarios in an ASP.NET website. Specifically, it examines how to use the Windows Communication Foundation, or WCF, to serve data from the web server and how to use both the ASP.NET Ajax Library and jQuery to consume such services from the client-side. Read on to learn more!
A Brief Primer on the Windows Communication Foundation
Throughout this article series we've been examining ways to access server-side data from client-side script. In Part 1 the server-side data - namely category and product information from the Northwind database - was exposed by an ASP.NET page. Specifically, the ASP.NET page's
Page_Load
event handler examined the requested
URL to determine whether the requestor wanted category information or product information. It then returned the requested data as a JSON-formatted string.
In Part 2 we exposed the server-side data using an Ajax Web Service. With the Ajax Web Service,
we didn't need to write any code to parse the incoming URL or to format the outgoing markup into JSON - that was handled for us by
the .NET Framework. Instead, we focused on writing the code to retrieve and return the data of interest.
The Windows Communication Foundation, or WCF, is a large collection of classes in the .NET Framework designed to assist developers in building connected,
service-oriented applications, and was added to the .NET Framework in version 3.0. WCF is used to build services, which are programs that reside at a particular
endpoint and can be invoked by a client application. Typically, the endpoint for a WCF service is a URL like http://www.yourserver.com/ServiceName.svc
.
Clients that wish to communicate with the service would send a properly formatted message to the endpoint. Upon receiving this message, the service would execute its
code and, perhaps, return data back to the client.
WCF services are a lot like Ajax Web Services in the sense that they allow us, the developer, to focus on implementing the service; we are alleviated from having to
parse the incoming request and from deseriealizing the incoming inputs and serializing the output into JSON. WCF is a much more powerful communications framework than
ASP.NET's .asmx
Web Services we examined in Part 2. For example, recall that the Ajax Web Service we created in Part 2 did not return a native JSON
representation of the category or product data returned. Instead, it included the type name of each category or product returned and wrapped these results into an
object with a property named d
. This customized format was the format expected by the ASP.NET Ajax Library, but when calling the Ajax Web Service using
jQuery we had to jump through a few hoops to get everything to work. As we'll see momentarily, with WCF services you can specify whether to return the native JSON or
whether to return the customized JSON format expected by the ASP.NET Ajax Library.
This article shows how to create the same server-side functionality implemented in Parts 1 and 2, but using a WCF service instead of an ASP.NET page or Ajax Web Service. We'll see how to consume a WCF service from the browser using both the ASP.NET Ajax Library and jQuery.
Adding a WCF Service To Your Website To Be Consumed By The ASP.NET Ajax Library
To add a WCF service to your website add a new item of type "AJAX-enabled WCF Service" (see the screen show below). For the demo (available for download at the end of this article) I named this AJAX-enabled WCF Service
NorthwindFormatted.svc
, adding it to the Services
folder.

The name of your WCF service - NorthwindFormatted.svc
in my example - is the endpoint for the service. Because it is located in the Services
folder,
clients will access it by visiting http://www.mysite.com/Services/NorthwindFormatted.svc
. The actual NorthwindFormatted.svc
file serves as a placeholder
of sorts - it does not contain any code. Rather, the service's code is located in a separate file named NorthwindFormatted.vb
or NorthwindFormatted.cs
and is where we define the methods that make up our service. At this point the code file should have the following code:
[ServiceContract(Namespace = "")]
|
There are a number of attributes in this class and on its methods. The ServiceContract
attribute defined at the class level indicates that this class represents
a service contract for a WCF service; the OperationContract
attributes defined on the class's methods indicate what methods of the class can be invoked
by a client. The AspNetCompatibilityRequirements
attribute defined on the class indicates that the WCF service should be allowed to access ASP.NET information,
such as session state and the ASP.NET intrinsic objects (Request
, Response
, Server
, etc.).
For now, clear out the DoWork
method and add the following GetCategories
and GetProductsByCategory
methods. The code in these
two methods is identical to that code presented in Part 2 of this article series - Using Ajax Web Services,
Script References, and jQuery. The only difference here is that instead of using the WebMethod
attribute (as we did with the Ajax Web Service), we
instead use the OperationContract
attribute.
[ServiceContract(Namespace = "")]
|
When you added the AJAX-enabled WCF Service to your website, Visual Studio added not only the NorthwindFormatted.svc
and NorthwindFormatted.svc.cs
(or NorthwindFormatted.svc.vb
) files, but also modified your application's Web.config
file, adding a <system.serviceModel>
element with a mess of configuration information. You can optionally remove this configuration markup by adding a Factory
attribute to the .svc
file's
<%@ ServiceHost %>
directive. Personally, I prefer removing this configuration and using the Factory
attribute and have done so in the demo application.
To follow along on your application, open Web.config
and remove the entire <system.serviceModel>
element (which was just added by Visual
Studio when adding the WCF service). Next, open the NorthwindFormatted.svc
file and add the following Factory
attribute to the
<%@ ServiceHost %>
directive like so:
<%@ ServiceHost Language="C#" Debug="true" Service="NorthwindFormatted"
|
Calling the WCF Service Using the ASP.NET Ajax Library
Part 2 of this article series examined how to call a server-side Ajax Web Service from a browser using the ASP.NET Ajax Library. In short, the ASP.NET Ajax Library creates a JavaScript proxy class that can be called from the script in the web page. Invoking the proxy class's methods sends an asynchronous HTTP request to the server and a specified function is executed once the response is received.
Calling a WCF service from the browser using the ASP.NET Ajax Library involves nearly the same steps as calling an Ajax Web Service. First, we need to create the proxy class. This is accomplished by adding a ScriptManager control to the web page and adding a script reference to the WCF service like so:
<asp:ScriptManager ID="ScriptManager1" runat="server">
|
Note: If you have a ScriptManager already defined in your master page you can either add the script references to that ScriptManager or, better yet, you can add a ScriptManagerProxy control to your ASP.NET page and define the services there.
This addition causes the ScriptManager to automatically generate a JavaScript proxy class and make it accessible to the page. To call the WCF service from JavaScript
you simply enter the fully qualified type of the Web Service (such as NorthwindFormatting
or, if you have placed the Web Service in a namespace, then
Namespace.NorthwindFormatting
), passing in any parameters. The proxy class calls the service asynchronously, meaning that you need to provide a
JavaScript function that will be called once the WCF service call completes and returns a result. It is from this function that you'll update the page's display to
incorporate the information returned by the service. (You can also specify a function to call if the service call resulted in an error.)
The JavaScript for populating the drop-down list with the set of categories follows. We start by calling the NorthwindFormatting.GetCategories
method, specifying
the function to execute when the response returns as the first parameter of this method. This "on success" function is passed the data returned by the WCF service, which
we then enumerate using jQuery's $.each
function, adding a new <option>
element to the drop-down for each category returned by the service.
// Populate the categories DDL
|
As you can see, the above script is nearly identical to the script used when calling an Ajax Web Service. The only difference is that the WCF service proxy class
is named NorthwindFormatted
, whereas the Ajax Web Service proxy class was named NorthwindService
. Other than that minute difference, the
scripts are identical.
If you use a tool like Fiddler you can inspect the information exchanged between the client and the server. When
calling the NorthwindFormatted.GetCategories
function from script, the browser sends the following HTTP request (some headers have been removed for
brevity):
POST http://localhost:3028/AccessDataFromScript3/Services/NorthwindFormatted.svc/GetCategories HTTP/1.1
|
Note that the request was made to NorthwindFormatted.svc/GetProductsByCategory
. When the request arrives at the server, ASP.NET parses this URL and knows
to invoke the GetProductsByCategory
method in the NorthwindFormatted
WCF service. Also note that this HTTP request uses the POST
verb
and sets the Content-Type
header to application/json
. As discussed in Part 2, this is the manner by which the ASP.NET Ajax Library's proxy
classes make requests to the server, namely as POST
s with an appropriately specified Content-Type
.
The response sent back to the browser from the server contains the following (abbreviated and formatted) JSON:
{
|
Note how the JSON data is not a native representation of the returned type (namely, an array of CategoryDTO
objects), but instead is an object with a
single property (d
) that is assigned an array of objects. Each object in the d
array contains the serialized properties of the CategoryDTO
class along with a __type
property. As discussed in Part 2, this is the JSON format used to return data from an Ajax Web Service and it the format
expected by the ASP.NET Ajax Library on the client-side.
Because the WCF service accepts requests in the format the ASP.NET Ajax Library's proxy class sends it - as a POST
request - and because it returns the results
using the customized JSON serialization - namely, the single object with a property d
that contains the actual results - the ASP.NET Ajax Library can
seamlessly consume such a WCF service. But what about jQuery? In Part 2 we saw how to use jQuery to call an Ajax Web Service and those same steps could be applied here
to call the WCF service we just created. However, as we'll see momentarily, it is possible to create a WCF service that formats the data returned by the service as
native JSON (rather than using the custom format expected by the ASP.NET Ajax Library).
Adding a WCF Service To Your Website To Be Consumed By jQuery
The WCF service we just created -
NorthwindFormatted.svc
- parses the incoming information and formats its output in such a way as to facilitate it
being called by a proxy class created by the ASP.NET Ajax Library. Other JavaScript libraries, such as jQuery, are not designed to handle this custom format natively.
As we saw in Part 2, in order to invoke an Ajax Web Service from jQuery and parse the results we need to write a bit more script than when calling a service that does
not apply this custom formatting.
The good news is that it's quite easy to create a WCF service that accepts GET
HTTP requests and natively formats the returned object into JSON (rather than
creating a new object with the d
property). Such a service can be called without any fuss from jQuery. The demo project available at the end of this article
includes an additional WCF service in the Services
folder named NorthwindNative.svc
. This service was created in the same fashion as
NorthwindFormatted.svc
- namely, I added a new AJAX-enabled WCF Service to my website. As before, adding this service prompts Visual Studio to add
a <system.serviceModel>
element to Web.config
, which I've deleted.
The NorthwindNative
code file contains the exact same code as NorthwindFormatted
code file with one important addition - a new attribute indicating
how the GetCategories
and GetProductsByCategory
methods can be invoked from a client. Specifically, I've added a WebInvoke
attribute that specifies two things: that the method will be invoked via a GET
request and that the data should be returned as JSON (as opposed to XML).
public class NorthwindNative
|
Another difference is that in the NorthwindNative.svc
file I've added a Factory
attribute that references the class
WebServiceHostFactory
instead of WebScriptServiceHostFactory
, which is what was used for the NorthwindFormatted
service.
<%@ ServiceHost Language="C#" Debug="true" Service="NorthwindFormatted"
|
And that's all there is to it!
Because these methods are now accessible via an HTTP GET you can "run" them by pointing your browser to Services/NorthwindNative.svc/MethodName
.
For instance, going to http://www.yoursite.com/Services/NorthwindNative.svc/GetCategories
should return the following (formatted and abbreviated) JSON payload:
[
|
The above payload is the native serialization of the CategoryDTO
objects returned by the service. There's no custom formatting involving wrapping the
returned objects in an object with a d
property and adding a __type
property to each CategoryDTO
.
To call a method with input parameters, such as GetProductsByCategory
, you specify the parameters as querystring values, like so:
http://www.yoursite.com/Services/NorthwindNative.svc/GetProductsByCategory?CategoryID=categoryId
. (There is a way to customize the URL pattern used
to call the service and supply its input parameters; we'll examine how to make such customizations in a future article in this series.)
Calling the NorthwindNative.svc
Service from jQuery
The JavaScript you need to write to invoke the
NorthwindNative.svc
service form jQuery is nearly identical to the script examined in
Part 1. Namely, we use jQuery's $.getJSON
function to make an HTTP request to the
service and then execute script once the service responds with the results. The following snippet shows how to use jQuery's $.getJSON
and
$.each
functions to make a request to NorthwindNative.svc/GetCategories
and then add the results to the items in the categories
drop-down list.
$.getJSON('Services/NorthwindNative.svc/GetCategories',
|
Download the demo to explore a complete working example of accessing the NorthwindFormatted.svc
and NorthwindNative.svc
WCF services using the
ASP.NET Ajax Library and jQuery, respectively.
Happy Programming!
Attachments:
Further Reading