Click here to Skip to main content
Click here to Skip to main content

Responsive WCF service With ICallbackEventHandler Interface

, 6 Aug 2012
Rate this:
Please Sign up or sign in to vote.
Responsive WCF service With ICallbackEventHandler Interface
This is an old version of the currently published article.

Introduction 

In this post I am going to discuss about the development of the WCF(duplex) callback service which replay back to consumer i.e client of service and about ICallbackEventHandler Interface implementation which provide response to the user on screen.

Here I designed WCF service which is place order for client and reply back to client that order placed successfully or not. ICallbackEventHandler interface implemented on page display response to client. Before I discuss more here is the screen that shows output
Place Order
WCF service placing order

Order placed successful or not

To accomplish this whole program get divide in two part 1) Design of callback WCF service 2) Design of WEB page with ICallbackEventHandler interface to provide response on screen


Design of callback WCF service Config file

You need to config WCF service as below to make service reliable(duplex) i.e send response back to client once task done.

<configuration>
  <system.servicemodel>
    <bindings>
      <wsdualhttpbinding>
        <binding bypassproxyonlocal="true" name="sampleBinding" usedefaultwebproxy="true">
      </binding></wsdualhttpbinding>
    </bindings>
    <services>
      <service behaviorconfiguration="returnFaults" name="Service.DemoService">
        <endpoint binding="wsDualHttpBinding" bindingconfiguration="sampleBinding" contract="Service.IDemoService">
      </endpoint></service>
    </services>
    <behaviors>
      <servicebehaviors>
        <behavior name="returnFaults">
          <servicedebug includeexceptiondetailinfaults="true">
          <servicemetadata httpgetenabled="true">
        </servicemetadata></servicedebug></behavior>
      </servicebehaviors>
    </behaviors>
  </system.servicemodel>
  <system.web>
    <compilation debug="true">
  </compilation></system.web>
</configuration> 

Thing to note in config file is used protocol called "wsDualHttpBinding" that allows to create reliable session that means it allows to send response back to client who made call to service once task get completed.
WSDualHttpBinding - A secure and interoperable binding that is designed for use with duplex service contracts that allows both services and clients to send and receive messages.


WCF Service file
After creating or modifying you can code service file as below.

using System;
using System.ServiceModel;
using System.Collections.Generic;
using System.Threading;
using System.Runtime.Serialization;

namespace Service
{
 
IDemoService- interface that is implemented in WCF service. whose method get called by application consuming wcf service.
[ServiceContract(CallbackContract = typeof(IClientCallBack))]
    public interface IDemoService
    {
        [OperationContract(IsOneWay = true)]
        void PlaceOrder(OrderItem item);
    }

ServiceContractAttribute.CallbackContract - This attribute allows to set callback contract when the contract is a duplex contract i.e callback interface that get called by service to inform client.
So this allows client applications to listen for inbound operation calls that the server-side service application can send to client application which is independent from client activity. Callback contracts that have one-way operations represent calls from the service that the client can handle.

IClientCallBack- interface that is get implemented on the client side i.e by the application which is consuming the wcf service. Method of this interface get called from wcf service methods which is discussed below.

public interface IClientCallBack
    {
        [OperationContract(IsOneWay = true)]
        void ISOrerPlaceSuccessfully(bool issuccess, float total);
    }
OrderItem - is datacontract class of wcf service.
[DataContract]
    public class OrderItem
    {
        float price;
        string name;
        int qty;
        [DataMember]
        public float Price
        {
            get { return price; }
            set { price = value;}
        }

        [DataMember]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        [DataMember]
        public int Quantity
        {
            get { return qty; }
            set { qty = value; }
        }
    }
DemoService - Implement service contract interface.
public class DemoService : IDemoService
    {
        public void PlaceOrder(OrderItem item)
        {
            IClientCallBack callback = OperationContext.Current.GetCallbackChannel<IClientCallBack>();
            bool success = true;
            //process order 
            float total = item.Price * item.Quantity;
            callback.ISOrerPlaceSuccessfully(success, total);
        }
    }
}

PlaceOrder - method call the callback contract method ISOrerPlaceSuccessfully.
OperationContext.Current -Gets the execution context for the current thread.
code uses the Current property and GetCallbackChannel method to create a channel back to the caller i.e to client from service method. one-way method allows service and client to communicate in both directions independently.


Design of WEB page with ICallbackEventHandler interface to provide response on screen

.ASPX file

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebClient.Default" EnableSessionState="True"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body id="formBody" runat="server" >
    <form id="form1" runat="server">
    <div style="text-align:center">
      <h1>Place Order</h1>
    </div>
    <div>
        <table>
           <tr>
             <td><asp:Label ID="lblItemName" runat="server" Text="Label">Item Number :</asp:Label></td>
             <td><asp:Label ID="lblItemValue" runat="server" Text="Label">Test</asp:Label></td>
           </tr>
           <tr>
             <td><asp:Label ID="Label1" runat="server" Text="Label">Price :</asp:Label></td>
             <td><asp:Label ID="Label2" runat="server" Text="Label">500</asp:Label></td>
           </tr>
           <tr>
             <td><asp:Label ID="Label3" runat="server" Text="Label">Qunatity :</asp:Label></td>
             <td><asp:TextBox ID="txtQunatity" runat="server" ></asp:TextBox></td>
           </tr>
        </table>
        <asp:Button ID="Button1" runat="server" Text="Place Order" OnClick="Button1_Click" />
        <asp:Label ID="lblMsg" runat="server"></asp:Label></div>
    
    </form>
</body>
</html>

.Cs file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WebClient.DemoService;
using System.ServiceModel;
using System.Threading;

namespace WebClient
{

Implementation of Clicent callback interface - here all method declare in service as part of callback contract get implemented. This method is get called by the service method once task done on service side.
public class CallBack : WebClient.DemoService.IDemoServiceCallback
    {
        public string Message
        {
            get;set;
        }
        public void ISOrerPlaceSuccessfully(bool issuccess, float total)
        {
            Thread.Sleep(5000);
            if (issuccess)
                this.Message = "Order with total of : " + total + " placed successfully";
            else
                this.Message = "Order with total of : " + total + " failed to place";
        }
    }

ISOrerPlaceSuccessfully - is callback method which is get called back from the placeorder method of service. Once response is arrived Message property value get updated which is used to show the order stats on user screen. Note - Thread.Sleep is used in code just for the delay/demo purpose i.e to show the how it actually works when longer process get called on service. Remove it when make use in project.
ICallbackEventHandler Interface - Used to indicate that a control can be the target of a callback event on the server.
The ICallbackEventHandler is a wrapper on XMLHTTP. So that it allow to call the serverside method without any postback and there is no need to wirte any javascript/jquery for making ajax call all things get handle this interface in .net framework.
public partial class Default : System.Web.UI.Page, ICallbackEventHandler
    {
        static CallBack callback;
        DemoServiceClient client;
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            setupClientSideCallback();
            callback = new CallBack();
            InstanceContext ic = new InstanceContext(callback);
            client = new DemoServiceClient(ic);
            OrderItem item = new OrderItem();
            item.Name = "Test";
            item.Price = 12;
            item.Quantity = Convert.ToInt32(txtQunatity.Text);
            lblMsg.Text = "Placing Order...";
            client.PlaceOrder(item);
        }

Here in above code callback is variable of type Callback clas which is static because on the order pace button get clicked value of callback is remain as it is i.e its not get created again for later on use in GetCallbackResult method which is discussed below.

OnCallback is method defined at client side which is used to call back once the clientscript register by serverside code and eventArg is a variable defined at the client side which holds the parameter value.

protected void setupClientSideCallback()
        {
           string ScriptRef = this.ClientScript.GetCallbackEventReference(this, "'" + 0 + "'", "OnCallback", "'" + lblMsg.ClientID + "'");
            formBody.Attributes.Add("onload", ScriptRef);
            string script = "<script language="javascript" type="text/javascript">
 " +
                         " function getResponse() " +
                         " { " + ScriptRef + " } " +
                         " function OnCallback(Result,Context) " +
                         " { " +
                         " var lbl=document.getElementById(Context); " +
                          " lbl.innerText=Result ; " +
                          " setTimeout(getResponse, 1000); " +
                          " } " +
                         " 
</script> ";
            this.ClientScript.RegisterClientScriptBlock(this.GetType(), "ClientCallback", script);

        }

Javascript code - get register when placeorder button get clicked. After that to check the response arrived from the wcf service or not it makes call at regular interval by using setTimeout function. So it works like timer which execute set of code at regular interval.
The ICallbackEventHandler interface has two methods which required to be implemented in the page.

RaiseCallbackEvent - This event is called when the call from client side (Javascript)i.e from browser to server. This is the event to handle the call back handler. Here eventArgs is a parameter which is passed from client side.

GetCallbackResult - This methos returns the result of the callback event to client side i.e from serverside to browser.

string ICallbackEventHandler.GetCallbackResult()
        {
            if (callback!=null && callback.Message != null)
            {
                return  callback.Message;
            }
            return "Placing Order..." ;
        }

        string eventArgument;

        void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
        {
            this.eventArgument = eventArgument;
        } 
    }
}

Summary

WCF reliable(duplex) service useful to inform the cosumer of service i.e client of service that task completed or not by calling the consumer i.e client from service. This kind of suff useful when we are creating modules where payment of order take place as I did in my implementation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Pranay Rana
Software Developer (Senior) GMind Solusion
India India

Microsoft C# MVP (12-13)

 
Hey, I am Pranay Rana, working as a ITA in MNC. Web development in Asp.Net with C# and MS sql server are the experience tools that I have had for the past 5.5 years now.
 
For me def. of programming is : Programming is something that you do once and that get used by multiple for many years
 

You can visit my blog

StackOverFlow - http://stackoverflow.com/users/314488/pranay
My CV :- http://careers.stackoverflow.com/pranayamr
 
Awards:


Follow on   Twitter   LinkedIn

Comments and Discussions


Discussions posted for the Published version of this article. Posting a message here will take you to the publicly available article in order to continue your conversation in public.
 
Questionresponse using BasicHttpBinding Pinmemberagha_ali227-Aug-12 6:18 
AnswerRe: response using BasicHttpBinding PinmemberPranay Rana7-Aug-12 20:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140709.1 | Last Updated 6 Aug 2012
Article Copyright 2012 by Pranay Rana
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid