Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Exploring Windows Communication Foundation - Part 1

4.25/5 (38 votes)
31 Jan 2007BSD6 min read 1   725  
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