Getting Started with WCF

Welcome to the introductory tutorial for Windows Communication Foundation (WCF) on .NET Framework 3.5. This guide will walk you through the fundamental steps of creating and consuming a simple WCF service.

1. Introduction to WCF

Windows Communication Foundation (WCF) is a unified programming model for building service-oriented applications. It provides a robust and flexible framework for creating distributed systems, enabling communication between different applications and services across a network.

Key benefits of WCF include:

  • Interoperability: Supports various communication protocols (HTTP, TCP, MSMQ) and message formats (SOAP, REST).
  • Security: Built-in support for authentication, authorization, and message integrity.
  • Reliability: Features for ensuring message delivery and transaction management.
  • Extensibility: A rich extensibility model for custom behaviors and bindings.

2. Prerequisites

Before you begin, ensure you have the following installed:

  • Visual Studio 2008 or later (with .NET Framework 3.5 development tools)
  • .NET Framework 3.5 installed

3. Creating Your First WCF Service

Let's create a simple "Calculator" service.

3.1. Define the Service Contract

A service contract defines the operations that a service exposes to its clients. We'll use attributes to define this contract.


using System.ServiceModel;

namespace CalculatorService
{
    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        int Add(int a, int b);

        [OperationContract]
        int Subtract(int a, int b);

        [OperationContract]
        int Multiply(int a, int b);

        [OperationContract]
        int Divide(int a, int b);
    }
}
                

3.2. Implement the Service

Now, we implement the contract defined above.


using System.ServiceModel;

namespace CalculatorService
{
    public class Calculator : ICalculator
    {
        public int Add(int a, int b)
        {
            return a + b;
        }

        public int Subtract(int a, int b)
        {
            return a - b;
        }

        public int Multiply(int a, int b)
        {
            return a * b;
        }

        public int Divide(int a, int b)
        {
            if (b == 0)
            {
                throw new FaultException<string>("Cannot divide by zero.");
            }
            return a / b;
        }
    }
}
                

3.3. Configure and Host the Service

We need to configure our service and host it so clients can connect. For simplicity, we'll use a console application host.

Create a new Console Application project. Add a reference to your Calculator Service project.

App.config:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="CalculatorService.Calculator" behaviorConfiguration="CalcServiceBehavior">
        <!-- Service runs on either no base address or a base address specified here.
             This service derives the base address from the app.config configuration
             file: e.g.  -->
        <endpoint address="" binding="basicHttpBinding" contract="CalculatorService.ICalculator" />
        <!-- Metadata publishing can be disabled for security.
             Learn more about the service configuration file: http://go.microsoft.com/fwlink/?LinkId=255171 -->
        <mex endpointAddress="" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalcServiceBehavior">
          <!-- Service behaviors and tools -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
          <!-- To receive exception details in fault messages for debugging purposes, set the 'includeExceptionDetailInFaults' attribute to true.
               In production, this should be set to false. -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
                

Program.cs (Host):


using System;
using System.ServiceModel;

namespace CalculatorServiceHost
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(CalculatorService.Calculator)))
            {
                host.Open();
                Console.WriteLine("Calculator Service is ready.");
                Console.WriteLine("Press Enter to exit.");
                Console.ReadLine();
                host.Close();
            }
        }
    }
}
                

Note: For production environments, consider using IIS or Windows Service hosting for better management and reliability.

4. Creating a WCF Client

Now, let's create a client application to consume our Calculator service.

4.1. Add Service Reference

In your client project (e.g., a new Console Application), right-click on the "References" node in Solution Explorer and select "Add Service Reference...".

In the "Add Service Reference" dialog, enter the metadata exchange (MEX) address of your service. If you are running the host locally, this might be something like http://localhost:8731/Design_Time_Addresses/CalculatorService/Calculator/mex or the address specified in your host's configuration.

Click "Go" and then "OK". This will generate proxy classes for your service.

4.2. Consume the Service

Use the generated proxy to call the service operations.


using System;
using CalculatorServiceReference; // Namespace generated by Add Service Reference

namespace CalculatorClient
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // Create a client instance
                CalculatorClient client = new CalculatorClient();

                // Call the Add operation
                int resultAdd = client.Add(5, 3);
                Console.WriteLine($"5 + 3 = {resultAdd}");

                // Call the Subtract operation
                int resultSubtract = client.Subtract(10, 4);
                Console.WriteLine($"10 - 4 = {resultSubtract}");

                // Call the Multiply operation
                int resultMultiply = client.Multiply(6, 7);
                Console.WriteLine($"6 * 7 = {resultMultiply}");

                // Call the Divide operation
                int resultDivide = client.Divide(20, 5);
                Console.WriteLine($"20 / 5 = {resultDivide}");

                // Close the client gracefully
                client.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"An error occurred: {ex.Message}");
            }

            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();
        }
    }
}
                

5. Next Steps

Congratulations! You have successfully created and consumed a basic WCF service. From here, you can explore more advanced topics such as:

  • Different bindings (e.g., NetTcpBinding, WsHttpBinding)
  • Security configurations
  • Error handling with FaultException
  • Data contracts for complex data types
  • Hosting in IIS or as a Windows Service
  • RESTful services with WCF

Continue your learning journey by exploring the official WCF documentation and code samples.