Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A beginner’s guide for consuming a WCF service in JavaScript using ASP.NET AJAX

0.00/5 (No votes)
9 Feb 2009 1  
Shows how to use WCF in JavaScript.

Contents

Development Platform

  1. Visual Studio 2008 SP1
  2. .NET Framework 3.5 SP1
  3. ASP.NET AJAX
  4. IIS 7 or VS Integrated Web Server [WCF and SVS file configured]
  5. Windows Vista

ClientAjaxTodoApp.jpg

Introduction

WCF (Windows Communication Foundation) added a lot of new capabilities to the Microsoft application development platform, particularly in how applications communicate with each other. In this article, we are going to see how WCF can be used directly from a client-side JavaScript code. It is a very cool future provided by ASP.NET AJAX. In this article, we are not going to cover every theory about WCF internals, rather we only remain focused on how to use a service directly from JavaScript. So, no behind-the-scenes stuff on how ASP.NET or the .NET runtime manages this feature.

To demonstrate the ideas and facts, we are going create a demo solution with two projects. So, with no time waste, create a blank solution and save it. Now, add a Class Library project to the solution. Name the class library ServiceLibrary. Now, add a Web Application project to the solution and name it WEBUI. We are going to see two approaches to add a WCF Service that can be consumed from JavaScript.

  1. Using Ajax-Enable WCF Service item template
  2. Using Service Interface defined in a class library

Using an AJAX-Enabled WCF Service Item Template

Here, we will see a very straightforward way to use a WCF Service in JavaScript. Right click on the Web Application project and select Add New Item. Select AJAX-Enabled WCF Service Item Template, and name it “HelloWorldService.svc” and click OK. The wizard will add a HelloWorldService.svc file to the solution as expected. This file will have a code-behind file as well. If you open HelloWorldService.svc in an XML file editor, you will see a markup like this:

<%@ ServiceHost Language="C#" Debug="true" 
  Service="WebUI.HelloWorldService" CodeBehind="HelloWorldService.svc.cs" %>

ChooseItemTemplate.jpg

If you open the code-behind file, you will see code like this:

namespace WebUI
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = 
        AspNetCompatibilityRequirementsMode.Allowed)]
    public class HelloWorldService
    {
        [OperationContract]
        public void DoWork()
        {
            return;
        }
    }
}

Visual Studio 2008 automatically adds the necessary configurations for you in the web.config file, so no need to configure any thing in the web.config. Now, go ahead and add a HelloWorld() method which returns a string “HelloWorld”, and add a [OperationContract] attribute to the method. We will explain what the attributes are later in this article. Now, add a page to the Web Application project and name it “HelloWorldTest.aspx”. Drag and drop a Script Manager item from the Visual Studio tool box. Inside the ScriptManager tag, add a service reference to the service. An example code is given below:

<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Services>
        <asp:ServiceReference Path="~/HelloWorldService.svc" />
    </Services>
</asp:ScriptManager>

Now, add a button and a textbox to the page, and on the button click event, use a JavaScript function to call the Service. When you write the service call function, the Visual Studio 2008 HTML Editor will provide intellisense to write the necessary function call. The full HTML code is give below:

<form id="form1" runat="server">
<div>
    <script language="javascript" type="text/javascript">
        function GetValueFromServer() {
            HelloWorldService.HelloWorld(onSuccess, onFailure);
        }

        function onSuccess(result) {
            document.getElementById('txtValueContainer').value = result;
        }

        function onFailure(result) {
            window.alert(result);
        }
    </script>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Services>
            <asp:ServiceReference Path="~/HelloWorldService.svc" />
        </Services>
    </asp:ScriptManager>
    <input id="btnServiceCaller" type="button" value="Get Value" 
           onclick="GetValueFromServer()"; />
    <input id="txtValueContainer" type="text" value="" />
</div>
</form>

Note that when calling the service, we have passed two methods: one for the callback and the other for the error callback. If we need to pass any parameters to the function, the parameters will go first and then the callback. So, if we have a function named getvalue which takes two string parameters as arguments, we are going to call the function as [NameSpaceName].[ServiceName].getvalue(“value one”,”value two”,on_success,on_error);, where on_sucess and on_error are the callback and the error callback, respectively.

Using a Service Interface Defined in the Class Library

So, we have looked at how to use an AJAX-enabled WCF Service using an item template. Now, we are going to see a more traditional WCF Service implementation, and we are also going to see how we can expose this service for ASP.NET AJAX. When we created the Class Library project, by default, it is not added with the service model and the runtime serialization support which is necessary to run WCF. So, we have to add the necessary service references. Go ahead and right click on the Class Library project and select Add Reference, and then select these references:

  • System.Runtime.Serialization
  • System.ServiceModel

ProjectOfTodo.png

In this phase, we are going to use a TODO Management example to demonstrate the whole idea. Add a Service based database, and then create a TODO table with ID, Description, and Status fields. Now, add a LINQ to SQL class file from the item template. Drag and drop the TODO table from database to the LINQ to SQL Class File Designer. Now, click on the designer surface and from the property window, change the serialization mode to Unidirectional. Now, our designer generated LINQ to SQL classes are ready to be used for WCF. If you want to use custom user defined types, you must set the [DataContract] class attribute to your class and you must add the [DataMember] property attribute to each property of the class you want to expose to WCF.

Now, we are going to add a service interface like this:

namespace ServiceLibrary
{
    [ServiceContract(Namespace = "ServiceLibrary")]
    interface IToDoService
    {
        [OperationContract]
        ToDo GetToDo(long ID);
        [OperationContract]
        ToDo AddToDo(ToDo toDo);
        [OperationContract]
        bool DeleteToDo(ToDo todo);
        [OperationContract]
        ToDo UpdateToDo(ToDo todo);
        [OperationContract]
        List<ToDo> GetAllToDo();
    }
}

Note that we have mentioned a namespace inside the ServiceContract interface attribute. This is very important. We are going to use this name as the service name inside the JavaScript code to access the services. Now, we are going to add the implementation to this service interface; the code is given below. Please note that in the code, I have used the [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] class attribute; this is a must requirement for exposing the service as an ASP.NET AJAX enabled WCF Service.

namespace ServiceLibrary
{
    [AspNetCompatibilityRequirements(RequirementsMode = 
        AspNetCompatibilityRequirementsMode.Allowed)]
    public class ToDoService : IToDoService
    {
        #region IToDoService Members
        public ToDo GetToDo(long ID)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var toDos = from p in context.ToDos
                        where p.ID == ID
                        select p;
            List<ToDo> listTodos =  toDos.ToList();
            if (listTodos != null && listTodos.Count > 0)
            {
                return listTodos[0];
            }
            else
            {
                return null;
            }
        }
        #endregion
    }
}

Configure a Web Application to Use the TODO Service

Now that we have defined all the necessary stuff to run our TODO application, it is time to expose the Service to the client as an ASP.NET AJAX enabled WCF Service. For this, we are going to add an AJAX-enabled WCF Service .svc file. And, we will get rid of the code-behind file. Or, we can add an XML file or a text file and then rename it to ToDoService.svc. Open it with an XML editor and add a directive like shown below:

<%@ ServiceHost Language="C#" Debug="true" Service="ServiceLibrary.ToDoService" %>

Now, we are going to put the necessary configuration to run this service in web.config. The code is given below:

<system.serviceModel>
  <behaviors>
   <endpointBehaviors>
    <behavior name="AspNetAjaxBehavior">
     <enableWebScript />
    </behavior>
    <behavior name="WebUI.HelloWorldServiceAspNetAjaxBehavior">
     <enableWebScript />
    </behavior>
   </endpointBehaviors>
  </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  <services>
   <service name="ServiceLibrary.ToDoService">
    <endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding"
     contract="ServiceLibrary.IToDoService" />
   </service>
   <service name="WebUI.HelloWorldService">
    <endpoint address="" behaviorConfiguration="WebUI.HelloWorldServiceAspNetAjaxBehavior"
     binding="webHttpBinding" contract="WebUI.HelloWorldService" />
   </service>
  </services>
</system.serviceModel>

Now, right click on the file and select View in Browser to see the service up and running well. A few things must be mentioned before moving to the next phase. You must add a serviceHostingEnvironment and set aspNetCompatibilityEnabled="true" to be able to use a WCF Service in ASP.NET with its features like HTTP Context, Session etc.

Using the Service in JavaScript

Now, use the service just like the HelloWorldService we previously used. Below, I have given example code to make things clear. The ScriptManager markup is also shown. Note that we have added a clientServiceHelper.js file. We have put all the client to WCF communication JavaScript functions in that file.

<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/Script/ClientServiceHeler.js" />
    </Scripts>
    <Services>
        <asp:ServiceReference Path="~/ToDoService.svc" />
    </Services>
</asp:ScriptManager>

We have used an ASP.NET AJAX client-side object oriented model to write the JavaScript client-code which is part of clientServiceHelper.js.

Type.registerNamespace("ServiceClients");
    ServiceClients.ToDoClient = function() {
}

ServiceClients.ToDoClient.prototype = {

    AddToDo: function(todo, callback, errorCallBack) {
        ServiceLibrary.IToDoService.AddToDo(todo, callback, errorCallBack);
    },

    DeleteToDo: function(todo, callback, errorCallBack) {
        ServiceLibrary.IToDoService.DeleteToDo(todo, callback, errorCallBack);
    },

    UpdateToDo: function(todo, callback, errorCallBack) {
        ServiceLibrary.IToDoService.UpdateToDo(todo, callback, errorCallBack);
    },

    GetAllToDo: function(callback, errorCallBack) {
        ServiceLibrary.IToDoService.GetAllToDo(callback, errorCallBack);
    },

    dispose: function() {
    }
}

ServiceClients.ToDoClient.registerClass('ServiceClients.ToDoClient', null, Sys.IDisposable)

if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

Summary

In this article, we have seen how we can use an AJAX-enabled WCF Service Item Template. Then, we saw how we can use a service interface based WCF Service. We also saw how to configure the web.config to use the Services. Last of all, we saw how we to add a service reference in ScriptManager. A few things must be mentioned before ending this article. We can also add a service reference in the C# code. A simple code example is given below:.

ScriptManager manager = ScriptManager.GetCurrent(Page);
ServiceReference reference = new ServiceReference("ToDoService.svc");
manager.Services.Add(reference);

If beginners encounter problems or do not understand any particular portion of the article, please drop me a message. You can learn the ABCs of WCF here. If you have any difficulty configuring WCF in IIS, please see the article here.

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here