Bernie Cook's Blog

Azure, C#, .NET, Architecture & Related Tech News

Consuming a WCF Service with jQuery or ScriptManager

4 Comments

I recently created a working example of WCF service that is consumed by both a jQuery AJAX call and a ScriptManager AJAX call. I was interested to see how the WCF improvements offered by .NET 4 compared with the latest jQuery library (v1.7.1 at the time of writing). You can download the solution’s source code or take a look through this post where I discuss the particulars of this comparison.

Before delving into the code I want to point out a few things; (1) I’ve cut out all of the extraneous code from this sample so what’s included is the bare essentials in order to get the sample working (unless otherwise indicated), (2) this post assumes you are familiar with WCF, AJAX, jQuery, and ScriptManager, and (3) I have avoided implementing a DataContract, again to keep it simple.

Solution

There are two projects in this solution, an ASP.NET Web Application which contains the jQuery and ScriptManager calls, and the Class Library which serves as the Service Library. The web application references the service library.

The solution’s source code (AJAXEnabledWCFService.zip) can be downloaded via Google Docs.

Service Library

For good practice I decoupled the service implementation from the presentation layer, hence having two projects rather than just the one web application. A much simpler alternative, recommended for very small projects, is to create an “AJAX-enabled WCF Service” item within the web application. This would actually have been fine but I wanted to expose a service within my web application that mapped to my WCF Service Library’s service and this wouldn’t have been possible with the aforementioned approach. In addition, I created a Class Library rather than a WCF Service Application as I prefer to add project code myself and not have to strip out a lot of unnecessary Visual Studio template code.

The Service Library contains a simple service with one method; GetAllCountries(), which accepts no parameters and returns a JSON-formatted response of country names. Note that I don’t have to explicitly state the response format as JSON is the default.

IEurope.cs

namespace ServiceLibrary.Countries
{
    [ServiceContract(Namespace = "Countries")]
    public interface IEurope
    {
        [OperationContract]
        List GetAllCountries();
    }
}

Europe.cs

namespace ServiceLibrary.Countries
{
    public class Europe : IEurope
    {
        public List GetAllCountries()
        {
            List allCountries = new List();

            allCountries.Add("Albania");
            allCountries.Add("Andorra");
            // More countries added.
            allCountries.Add("United Kingdom");
            allCountries.Add("Vatican City");

            return allCountries;
        }
    }
}

Web Application

There is a short-list of files in the web application, the most important being the one which maps the AJAX calls to the Service Library; Europe.svc.

Europe.svc

<%@ ServiceHost Service="ServiceLibrary.Countries.Europe" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>

This one simple line has the Service attribute pointing at the Service Library service; Europe. Followed by the Factory attribute that references the WebScriptServiceHostFactory which “automatically adds an ASP.NET AJAX endpoint to a service, without requiring configuration, in a managed hosting environment that dynamically activates host instances for the service in response to incoming messages” – MSDN.

Web.Config

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
</configuration>

If you’ve had some experience with WCF you’ll notice the most obvious difference is that there is absolutely no endpoint configuration settings. I’ve read, and been told, that you still need to keep the <standardendpoints> node and it’s child nodes, however I removed this from the solution and noticed no difference. The default values are adequate for this solution and the WebScriptServiceHostFactory does the remainder of the heavy lifting – you can start to see how much easier this is. Don’t get me wrong, I’d still recommend that developers implementing this type of code have a solid grasp of the ABCs of WCF as there are a lot of WCF considerations to address once you move away from your basic web application – security, performance, maintainability etc.

jQuery

Before I get into the JavaScript you can see that the <body> only contains a button, and a div for outputting my responses. The header contains a jQuery reference followed by a single function which is called by the buttons onclick event and performs the asynchronous HTTP request: $.ajax.

jQuery.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="jQuery.aspx.cs" Inherits="WebApplication.jQuery" %>
<html>
<head>
    <title>jQuery</title>
    <script src="Resources/JavaScript/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        //<![CDATA[

        function Test()
        {
            $.ajax(
            {
                type: "POST",
                contentType: "application/json;charset=utf-8",
                url: "Services/Countries/Europe.svc/GetAllCountries",
                data: null,
                dataType: "json",
                beforeSend: function (jqXHR, settings)
                {
                    $("#divOutput").append("<br/>Before send...");
                },
                success: function (response, status, jqXHR)
                {
                    // The ".d" property is the name for the name/value JSON response.
                    for (i in response.d)
                        $("#divOutput").append("<br/>" + response.d[i]);

                    $("#divOutput").append("<br/>Success.");
                },
                    error: function (jqXHR, status, error)
                {
                    $("#divOutput").append("<br/>Error " + jqXHR.responseText);
                },
                complete: function (jqXHR, status)
                {
                    $("#divOutput").append("<br/>Complete " + status + ".");
                }
            });
        }

        // ]]>
    </script>
</head>
<body>

    <h1>Using jQuery</h1>

    <form runat="server">

        <p>
            <input type="button" value=" Test " onclick="return Test();" />
        </p>

        Output:
        <div id="divOutput"></div>

    </form>

</body>
</html>

The jQuery AJAX API has an array of functions and methods, some of which are employed in the code above. There is one API function in particular; beforeSend which isn’t required but I’ve included it as it shows that you can use it to start up a loading animation, for example, while you’re waiting to receive an asynchronous response.

As the code reads – a click event fires a call to the JavaScript Test() method which makes an asynchronous AJAX POST request to GetAllCountries() exposed by the web application’s service mapping, which in turn calls the Service Library’s (similarly named) operation contract. The response returned is then dynamically inserted into the specified <div>. I’ve purposefully excluded posting any request data as I wanted to keep this simple. Once everything is wired up you can see it’s not too difficult to implement or understand.

ScriptManager

Contained within the System.Web.Extensions assembly (System.Web.UI namespace) is the ScriptManager class which “manages ASP.NET Ajax script libraries and script files, partial-page rendering, and client proxy class generation for Web and application services” – MSDN. It’s a powerful resource, which like jQuery, cuts down on a significant amount of development time and heavy lifting. You can see the tag at the bottom of the following code sample, referencing the web application’s .svc file. This allows you to make an asynchronous call to the GetAllCountries() method as illustrated in the JavaScript’s Test() function.

ScriptManager.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ScriptManager.aspx.cs" Inherits="WebApplication.ScriptManager" %>
<html>
<head>
    <title></title>
    <script type="text/javascript">
        //<![CDATA[

        function Test()
        {
            Countries.IEurope.GetAllCountries(OnRequestComplete, onError);
        }

        function OnRequestComplete(response, state)
        {
            for (i in response)
                document.getElementById("divOutput").innerHTML += "<br/>" + response[i];
        }

        function onError()
        {
            document.getElementById("divOutput").innerText = "Error";
        }

        // ]]>
    </script>
</head>
<body>

<h1>Using ScriptManager</h1>

    <form runat="server">

        <p>
            <input type="button" value=" Test " onclick="return Test();" />
        </p>

        Output:
        <div id="divOutput"></div>

         <asp:ScriptManager runat="server">
             <Services>
                 <asp:ServiceReference Path="~/Services/Countries/Europe.svc" />
             </Services>
         </asp:ScriptManager>

    </form>
</body>
</html>

The first thing that stands out when comparing the two methods is the amount of coding required. ‘Yes’ you don’t get a nice beforeSend type method with ScriptManager but look at how much less code there is.

If you look at the ScriptManager.aspx page’s source code from within your browser you’ll see (not too far from the bottom) a script reference to the web application’s service file:

<script type="text/javascript" src="Services/Countries/Europe.svc/jsdebug"></script>

If you enter this into the browser’s address bar you’ll get back some script which contains the JavaScript proxy code that does the bulk of the work. You can see how this dynamically generated code is tucked away so you can focus on what’s important when building your solution. If you remove the “debug” part from the end of the srcattribute’s value so you only have:

<script type="text/javascript" src="Services/Countries/Europe.svc/js"></script>

You’ll notice that you get back the JavaScript less the debugging code.

Comparison of jQuery and ScriptManager

Which approach is “better”? Personally I think it depends on a number of factors such as the technologies you’re encouraged to include (or avoid), the technical skills inherent to the developer building this part of your solution, whether you need to implement one of the additional jQuery.ajax() methods not made available via ScriptManager etc. At the end of the day it’s nice to know there is more than one option available when making WCF service calls from JavaScript. And I don’t see jQuery or ScriptManager disappearing anytime soon so both approaches are certainly future-proof … for the next few years anyway.

Download Source Code

The solution’s source code (AJAXEnabledWCFService.zip) can be downloaded via Google Docs.

Tools, Libraries & Frameworks

Here are several links to download the tools, libraries and frameworks referenced in this post:

Not essential, but a useful tool nonetheless, is Fiddler if you want to review the AJAX HTTP traffic.

Further Reading

Advertisements

Author: Bernie

I currently live and work in the UK, just outside of London. I've been working in IT for 15+ years and in that time have solved many technical problems via blogs, forums, tutorials etc. and feel like I should be giving something back. This blog post is my way of contributing and I hope it proves just as useful to others as their contributions have to me.

4 thoughts on “Consuming a WCF Service with jQuery or ScriptManager

  1. Thank you ! Thank you! Thank you! After 3 solid days of fighting with WCF to work with JQuery and downloading dozens of non-functioning examples, I found your page, downloaded the solution file, loaded into VS and , amazingly, it worked!!!
    I want to donate money to you, sir!

  2. Is there a way to get this service example to be public facing on the Internet?

  3. Nice article..

    But I have found another simple example to call a WCF RestFul Service using jQuery AJAX Call, please refer to link below:-
    http://www.etechpulse.com/2014/03/consume-restful-wcf-service-in-aspnet.html
    http://www.etechpulse.com/2014/03/how-to-consume-wcf-restful-service-in.html

    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s