Click here to Skip to main content
15,881,757 members
Articles / Programming Languages / C#
Article

Exploring Windows Communication Foundation - Part 1

Rate me:
Please Sign up or sign in to vote.
4.25/5 (38 votes)
31 Jan 2007BSD6 min read 128K   724   92   25
Starting with this article, we shall explore various aspects of WCF

Part 2 now available on Code Project at http://www.codeproject.com/WCF/edujini_wcf_scart_02.asp.
Also posted here at Eduzine©.

Exploring WCF (Part 1)

Introduction

Microsoft .NET Framework 3.0 introduces, among other components, Windows Communication Foundation or simply, WCF. The framework allows us, the development community, to build more service-oriented applications. It incorporates several Web Service related specifications, mostly driven by W3C and OASIS consortiums. I will just list a few of them:

  1. SOAP 1.1, 1.2 with Basic Profile 1.1
  2. WSDL 1.1
  3. MTOM
  4. WS Policy and WS Policy Attachments
  5. WS Metadata Exchange
  6. WSS SOAP Message Security 1.0, 1.1
  7. WSS SOAP Message Security Username Token Profile 1.0, 1.1
  8. WSS SOAP Message Security X.509 Token Profile 1.0, 1.1
  9. WS Addressing 2005/08
  10. WSS SOAP Message Security Kerberos Token Profile 1.1
  11. WS Secure Conversation
  12. WS Reliable Messaging
  13. WS Coordination
  14. WS Atomic Transaction
  15. WS Federation

Starting with this article, let us tour various key aspects of WCF.

Case Study

We shall take a simple shopping cart as a case-study. We start with simple data-types and slowly build on to work with custom, more complex data-types. In the sequence of articles, we shall explore various key aspects of WCF. The minimum features that I wish to explore in the series are:

  • Publishing WCF Service
  • Writing WCF Client
  • Customising the operation contract details, say decoupling the .NET and contract names or pushing part of the content in Headers of the SOAP-Envelope
  • Working with faults and errors
  • Working with custom data-types
  • Working with generic data in operations
  • Working with interface-types in operations
  • Working with collections in operations
  • Working with large data in operations
  • Working with sessions and transactions

Yeah.. it's a long list, but I'll try to fulfil my promise. No, all the articles are not ready right now. I will keep posting as and when they are ready, and also update this article with references to them.

Ok.. so, let's start!

We will need the following items to work with WCF:

  1. Microsoft .NET Framework 2.0 Redistributable here
  2. Microsoft .NET Framework 2.0 SDK here
  3. Microsoft .NET Framework 3.0 Redistributable here
  4. Microsoft Windows SDK for Windows Vista and .NET Framework 3.0 Runtime Components here You may download the complete image here
  5. If you are working with Visual Studio, download the extensions here

Service Definition

Our shopping-cart service, to begin with, publishes the following operations:

C#
bool      CheckUserExists(string username);
DateTime? GetLastTransactionTime(string username);

The job of the first operation is to check whether or not the user is registered in our database or not. The second operation returns the date and time of the last transaction done by the last user, if any. Yes, you note the operation correctly, the return type is not System.DateTime but System.DateTime?, the C# syntax for System.Nullable<System.DateTime>.

To publish any service in WCF, we require four steps in general:

  1. Service contract definition
  2. Contract implementation
  3. Service configuration
  4. Service hosting

Service Contract Definition

In WCF, service contract is the term used for the final service being published. Note that a service may have one or more related operations, referred to as operation contracts in WCF.

If you are working in Visual Studio, create a new project of type "Class Library". Yes, you read it right, it is "Class Library" and not "WCF Service Library".

We start by creating an interface IShoppingCartService as follows:

C#
using DateTime;

namespace ShoppingCartLibrary
{
    public interface IShoppingCartService
    {
        bool CheckUserExists(string username);
        DateTime? GetLastTransactionTime(string username);
    }
}

Contract Implementation

The next obvious step is to provide implementation to the service. We create a class ShoppingCartImpl that implements the interface IShoppingCartService.

C#
using DateTime;

namespace ShoppingCartLibrary
{
    public class ShoppingCartImpl : IShoppingCartService
    {
        public bool CheckUserExists(string username)
        {
            if(username == "gvaish" || username == "edujini")
            {
                return true;
            }
            return false;
        }

        public DateTime? GetLastTransactionTime(string username)
        {
            if(username == "gvaish")
            {
                return DateTime.Now.AddDays(-3);
            }
            if(username == "edujini")
            {
                return DateTime.Now.AddHours(-3);
            }
            return null;
        }
    }
}

Service Configuration

We need configuration at two levels:

  1. Using attributes, we need to tell WCF about the service contract and operation contracts. The information would be used to define service, operations, messages and types
  2. Using configuration entries, we need to tell WCF about the implementation class to be used and binding details. These details would be used for hosting purposes.

Contract Configuration

If you are using Visual Studio, add a reference to the assembly System.ServiceModel.dll from GAC. Add the attribute System.ServiceModel.ServiceContractAttribute to the interface. It tells the WCF that there is a service associated with the corresponding type. Add the attribute System.ServiceModel.OperationContractAttribute to the methods in the interface. It informs the WCF about the operations to be published in the service. It will take care of messages and types associated on its own.

So, our final code looks as follows:

C#
using DateTime;
using ServiceModel;

namespace ShoppingCartLibrary
{
    [ServiceContract]
    public interface IShoppingCartService
    {
        [OperationContract]
        bool CheckUserExists(string username);

        [OperationContract]
        DateTime? GetLastTransactionTime(string username);
    }
}

Service Configuration

We shall provide these details to our hosting application.

Compile the files to the assembly. I name it ShoppingCartLibrary.dll. If you are compiling the code at the commandline, do not forget to add reference to System.ServiceModel.dll.

Service Hosting

Having defined our service completely, we need a runtime (engine) to host the service - an application that can allow the clients to connect and invoke the operations. For this, we shall create a console application. The application has just one class, MainClass, with the Main method.

For Visual Studio users, we name the project as ShoppingCartHost. Rename the class Program to MainClass.

Add a reference to System.ServiceModel.dll and to the ShoppingCartLibrary.dll Write the following code to the MainClass.

C#
using System;
using System.ServiceModel;
using ShoppingCartLibrary;

namespace ShoppingCartHost
{
    public class MainClass
    {
        public static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:8080/ShoppingCartService");

            using(ServiceHost host = new ServiceHost
                    (typeof(ShoppingCartImpl), uri))
            {
                host.Open();

                Console.Write("Hit <Enter> to stop service...");
                Console.ReadLine();
            }
        }
    }
}

Now, we need the service configuration as mentioned earlier. Write the following code to the application configuration file.

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="HttpGetBehaviour">
                    <serviceMetadata httpGetEnabled="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="ShoppingCartLibrary.ShoppingCartImpl"
                behaviorConfiguration="HttpGetBehaviour">
                <endpoint binding="mexHttpBinding"
                    contract="ShoppingCartLibrary.IShoppingCartService" 
                                address=""/>
            </service>
        </services>
    </system.serviceModel>
</configuration>

Compile your code. Start the console application. You should see your server up and running.

host application

Browse to the location http://localhost:8080/ShoppingCartService.

browse location

Hurray! We are ready with our first service. Let's now design a client to consume the service.

Client Application

For our client, we need two items: the proxy client code and the configuration items. No no, you don't write any of them. You can generate them using the WCF tool svcutil.exe. You can locate this tool in the folder where your Visual Studio IDE is installed (default location being %PROGRAMFILES%\Microsoft Visual Studio 8\Common7\IDE) or where the .NET 3.0 SDK is installed (default location being %PROGRAMFILES%\Microsoft Windows SDK\v6.0\bin).

Ensure that the location to svcutil.exe is in your path. Invoke the following at commandline.

svcutil.exe /nologo /config:App.config 
        http://localhost:8080/ShoppingCartService?wsdl

It will generate two files: ShoppingCartImpl.cs and App.config. We just need a MainClass with Main method on the client side to consume the service published. Write the following code to the class:

C#
using System;

namespace ShoppingCartConsumer
{
    public class MainClass
    {
        public static void Main(string[] args)
        {
            ShoppingCartServiceClient client = new ShoppingCartServiceClient();

            string[] users = new string[] { "gvaish", "edujini", "other" };

            foreach(string user in users)
            {
                Console.WriteLine("User: {0}", user);
                Console.WriteLine("\tExists:  {0}", 
                client.CheckUserExists(user));
                DateTime? time = client.GetLastTransactionTime(user);
                if(time.HasValue)
                {
                    Console.WriteLine("\tLast Transaction: {0}", time.Value);
                } else
                {
                    Console.WriteLine("\tNever transacted");
                }
            }

            Console.WriteLine();
        }
    }
}

Don't forget to add a reference to System.ServiceModel.dll. Build your project. Execute the client. You should get an output similar to that shown below:

client application

Note that this is only a start... so, please have a little patience if you are looking for advanced topics.

Notes

We chose to have an interface as our service contract. In general, we can have a class directly as a service contract. However, it is always a good idea to have an interface and then provide an implementation. In this way, we can keep and maintain the declaration of the contract and implementation of the contract independently and modularly.

Summary

With WCF, it is possible to publish and consume web services in a very simple way. Publishing a web service is not as simple as in ASP.NET. However, as may be seemingly noticeable, the WCF may turn out to be much more flexible than ASP.NET service. One of the flexibilities that we saw was to host it outside ASP.NET Runtime.

Contact

  • You may directly put a comment below and I shall respond.
  • You can contact me directly at gaurav.vaish@gmail.com.
  • If you are looking for any professional work on Microsoft .NET Framework 2.0/3.0, Java 1.5/1.6, Web Services or Service Orientated Architecture (SOA), please contact my employer Edujini™ Labs at http://www.edujini-labs.com.

Version History

  • Initial submission
  • Updated introduction to something better than previous one
  • Provided details of the 2nd article of the series - now available at Code Project

License

This article, along with any associated source code and files, is licensed under The BSD License


Written By
Architect
United States United States

Gaurav lives in Silicon Valley.


His technical strength lies in having deep understanding of not one or two but bunch of enterprise frameworks.


Lately, he is working on an MVC framework implementation for Android put in open domain at http://sf.net/projects/android-mvc


Today, he is an independent guy:


  • He is a programming language independent guy, well almost. He is proficient in C, C++, Java, C#, VB.Net, C++.Net, JavaScript, PHP, Tcl, Python, Ruby
  • He is an OS independent guy, well almost. Has worked and developed at length on HP-UX, Linux (Redhat / Mandrake), Macintosh (9, 10.x), Windows (NT, 2000, 2003, XP, Vista), Solaris (8, 9, 10); and mobile platforms Android, iPhone, Blackberry
  • He is a target independent guy, well almost. Has worked on thick clients (mainly desktops) as well as thin clients (mainly alternative platforms - Symbian, PalmOS, WinCE, WinXP Embedded, Linux Embedded, Android, iPhone, Blackberry)



Today, his thrust areas are Service Oriented Architecture (implementation expert in Java, .Net and PHP; integration with Mainframe and other legacy environments), Mobile Technologies and RFID.



He holds a Bachelor's Degree (B. Tech.) from IIT Kanpur www.iitk.ac.in. His major was in EE with specialization in DSP (SSP).



His hobby is listening music, reading books (no, he can't read novels), photography and travelling.



Should you wish to talk to him, you can drop him a mail at gaurav[dot]vaish[at]gmail[dot]com. He generally responds within 24-48 hrs unless there is a compelling reason.



And yeah... here's his personal website:
http://www.m10v.com



Smile | :)


Comments and Discussions

 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey23-Mar-12 3:00
professionalManoj Kumar Choubey23-Mar-12 3:00 
GeneralNICE COPY AND PASTE JOB Pin
dick nigger23-Jun-10 17:16
dick nigger23-Jun-10 17:16 
GeneralVishal Sanchihar Pin
Prakshupa16-Sep-09 21:12
Prakshupa16-Sep-09 21:12 
GeneralVery usefull as starter Pin
RickNash30-Jan-08 5:08
RickNash30-Jan-08 5:08 
Generalsvcutil Pin
MG0215-Nov-07 10:55
MG0215-Nov-07 10:55 
GeneralRe: svcutil Pin
mastergaurav15-Nov-07 20:14
mastergaurav15-Nov-07 20:14 
GeneralGood article Pin
Steef-Jan Wiggers20-Oct-07 5:49
Steef-Jan Wiggers20-Oct-07 5:49 
GeneralRe: Good article Pin
mastergaurav20-Oct-07 18:16
mastergaurav20-Oct-07 18:16 
QuestionI get TCP error code 10061 when trying to add Service Reference to a Winforms Client Pin
dbaechtel17-Sep-07 14:53
professionaldbaechtel17-Sep-07 14:53 
GeneralTCP error code 10061: No connection could be made because the target machine actively refused it. Pin
ravijain21-Aug-07 20:44
ravijain21-Aug-07 20:44 
GeneralRe: TCP error code 10061: No connection could be made because the target machine actively refused it. Pin
mastergaurav30-Aug-07 23:42
mastergaurav30-Aug-07 23:42 
GeneralTCP error code 10061: No connection could be made because the target machine actively refused it. [modified] Pin
Amitabh Kumar Mishra1-Jun-07 23:49
Amitabh Kumar Mishra1-Jun-07 23:49 
GeneralRe: TCP error code 10061: No connection could be made because the target machine actively refused it. Pin
mastergaurav2-Jun-07 6:45
mastergaurav2-Jun-07 6:45 
GeneralRe: TCP error code 10061: No connection could be made because the target machine actively refused it. Pin
cankab7-Aug-07 23:22
cankab7-Aug-07 23:22 
GeneralError msg...No connection could be made because the target machine actively refused it Pin
PavanPT15-Apr-07 16:51
PavanPT15-Apr-07 16:51 
Hi there,
Im very much new to WCF and this article was very helpful. I am finding some difficulty in making the program work. When i run the program i get errors like

Could not connect to http://localhost:8080/ShoppingCartService. TCP error code 10061: No connection could be made because the target machine actively refused it.

I tried to add this port into firewall thinking that it mite be blocking but there is no change.

Is there anything else i have to do inorder to make it work.

Also,
I have to develope an application with muliple clients and a seperate "service host" and one service library.
Plz help me in this regard with possible internet resourses.

Kind regds,
Pavan

Pavan
Australia
AnswerRe: Error msg...No connection could be made because the target machine actively refused it Pin
mastergaurav20-Apr-07 6:29
mastergaurav20-Apr-07 6:29 
GeneralMSDN Magazine Pin
yuri kirilenko2-Feb-07 0:34
yuri kirilenko2-Feb-07 0:34 
GeneralRe: MSDN Magazine Pin
mastergaurav5-Feb-07 5:41
mastergaurav5-Feb-07 5:41 
GeneralIt will generate two files: ShoppingCartImpl.cs and... Pin
_JKON25-Jan-07 21:02
_JKON25-Jan-07 21:02 
GeneralRe: It will generate two files: ShoppingCartImpl.cs and... Pin
mastergaurav26-Jan-07 4:53
mastergaurav26-Jan-07 4:53 
GeneralWCF vs Remoting Pin
baruchl22-Jan-07 22:26
baruchl22-Jan-07 22:26 
GeneralRe: WCF vs Remoting Pin
mastergaurav23-Jan-07 4:05
mastergaurav23-Jan-07 4:05 
GeneralRe: WCF vs Remoting Pin
baruchl23-Jan-07 4:12
baruchl23-Jan-07 4:12 
GeneralRe: WCF vs Remoting Pin
mastergaurav27-Jan-07 6:06
mastergaurav27-Jan-07 6:06 
GeneralPart 2 of the series... [modified] Pin
mastergaurav22-Jan-07 20:31
mastergaurav22-Jan-07 20:31 

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

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