Web Services and WCF Tutorial

Views: This article has been read 49386 times.
Abstract: A WCF/Web Service tutorial describing in 23 steps the creation of a WCF service contract, implementation, generation of a proxy to host and run service, creation and configuration of a WCF client app, and the use of the proxy to call service operations.

Summary

The solution and projects used in this tutorial were created in C# using Visual Studio Express 2013 for Windows Desktop, and should be used for best results, or if one is familiar with the nuances between the different versions and their tools and templates. Be sure to launch VS.NET with Administrative rights. This will be required later to register HTTP addresses on your localhost for listening.

The following is a listed summary of what will be achieved after completing the 23 steps in this tutorial:

  • Create WCF service contract (VS.NET Class Library template)
  • Implement service contract with a service class (WCF application)
  • Generate Proxy to Host and Run WCF Service
  • Create and Configure WCF Client Application
  • Use Proxy (WCF Client) to Call Service Operations

Create WCF Service Contract

When creating a WCF service, the first task is to define a service contract. The service contract specifies what operations the service supports. An operation can be thought of as a Web service method. Contracts are created by defining an interface. Each method in the interface corresponds to a specific service operation. Each interface must have the ServiceContractAttribute ([ServiceContract] acceptable) applied to it and each operation must have the OperationContractAttribute ([OperationContract] acceptable) attribute applied to it. If a method within an interface that has the ServiceContractAttribute attribute does not have the OperationContractAttribute attribute, that method is not exposed by the service.

  1. Launch Visual Studio Express 2013 for Windows Desktop as administrator.
  2. Create a new Class Library project with the name WCFService and the solution name WCFServiceDemo (two more projects will be added later).
  3. Rename Class1.cs to WebService1 (the service name).
  4. Create an interface for WebService1 as your service contract and name it IService1 (select WebService1 and then select Project/Add New Item submenu … select Interface template).
  5. In the WCFService project, add System.ServiceModel and System.Runtime.Serialization references (select Add Reference submenu of References folder’s context menu [right click on folder in Solutions Explorer], select Assemblies/Framework and select the two references respective check boxes, select OK).
  6. Replace IWebService1 code with the following:
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }

Implement Service Contract with a Service Class

The next step in creating a WCF application is to implement the service interface. This involves creating a class called CalculatorService that implements the user-defined ICalculator interface.

  1. Create a CalculatorService class in WebService1.cs by adding the following code:
.
using System.Runtime.Serialization;
using System.ServiceModel;
.

public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            // Code added to write output to the console window.
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            Console.WriteLine("Received Subtract({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            Console.WriteLine("Received Multiply({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            Console.WriteLine("Received Divide({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
  1. Build Solution.

Generate Proxy to Host and Run WCF Service

  1. Create a new project (console application) under WCFServiceDemo solution and name it WCFServiceHost. This will be used to host the service.
  2. Add a WCFService reference to WCFServiceHost (select Add Reference from WCFService Host context menu, select Solution/Projects, select WCFService checkbox, select OK. NOTE: Make sure you had built your solution in earlier step before adding this reference).
  3. Add System.ServiceModel reference to the WCFServiceHost project.
  4. Add the following code to Main() in WCFServiceHost’s Program.cs file:
.
using System.ServiceModel;
using WCFService;
using System.ServiceModel.Description; 
.
static void Main(string[] args)
        {
            // Create instance of Uri class to hold base address of service
            Uri baseAddress = new Uri("http://localhost:8000/WCFServiceHost/");

            // Create ServiceHost instance to host service with contract implemented and base address 
            ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

            try
            {
                // Create ServiceEndpoint instance with service contract interface type, binding, and address
                selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");

                // Enable metadata exchange
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);

                // Start service
                selfHost.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press  to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                selfHost.Close();   // Close ServiceHostBase to shutdown service
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                selfHost.Abort();
            }
        }

Notice the creation of the ServiceHost instance to host the service and it exposing the contract implemented (CalculatorService) and the base address for the service, which will be used later by a client.

  1. Run WCFServiceHost in Visual Studio.
  2. Open Internet Explorer and browse to http://localhost:8000/WCFServiceDemo/. You should see the service's debug page.

NOTE: Adding a service endpoint is optional when using .NET Framework 4 or later. In these versions, if no endpoints are added in code or configuration, WCF adds one default endpoint for each combination of base address and contract implemented.

Create and Configure WCF Client Application

The following steps describe how to retrieve metadata from a WCF service and use it to create a WCF proxy that can access the service. This task is completed by using the Add Service Reference tool in Visual Studio. This tool obtains the metadata from the service’s MEX endpoint and generates a managed source code file for a client proxy. In addition to creating the client proxy, the tool also creates or updates the client configuration file which enables the client application to connect to the service at one of its endpoints.

NOTE: You can also use the ServiceModel Metadata Utility Tool (Svcutil.exe) tool to generate the proxy class and configuration instead of using Add Service Reference inside of Visual Studio.

  1. Create a new console application project named WCFServiceClient under WCFServiceDemo solution.
  2. Add a System.ServiceModel reference to WCFServiceClient.
  3. Launch WCFServiceHost.exe in WCFServiceHost project’s bin\Debug directory. This application must be running in order to complete the next step, adding a CalculatorService service reference to the host, WCFServiceHost.exe.
  4. Select Add Service Reference submenu from the WCFServiceClient/Service References folder’s context menu.
  5. In the Add Service Reference dialog, enter the following URL in the address field: http://localhost:8000/WCFServiceHost/ and select the Go button. The CalculatorService should display in the Services list box. If not, make sure WCFServiceHost.exe is running.
  6. Expand CalculatorService to display the service contracts implemented by the service (Operations: Add, Divide, Multiply, Subtract). Leave the default namespace (ServiceReference1) as is and click the OK button to add the service reference.

The next steps describe how to configure the WCF client. Configuring the client consists of specifying the endpoint that the client uses to access the service.

  1. Open the generated configuration file (App.config) from the WCFServiceHost project and replace its code with the following (note the endpoint specified to call CalculatorService):

Settings for app.config file

Use Proxy (WCF Client) to Call Service Operations

Once a Windows Communication Foundation (WCF) proxy has been created and configured, a client instance can be created and the client application can be compiled and used to communicate with the WCF service.

  1. Add the following code to Program.cs file in WCFServiceClient, which is used to instantiate the WCF proxy and call each of the service operations exposed by the service:
.
using WCFServiceClient.ServiceReference1;
.

namespace WCFServiceClient
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create instance of WCF proxy
            CalculatorClient client = new CalculatorClient();

            // Call the Add service operations 
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

            // Call the Subtract service operation
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

            // Call the Multiply service operation
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Call the Divide service operation
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

            // Close client gracefully and cleans up resources
            client.Close();
        }
    }
}
  1. To test out the application, first run WCFServiceHost to start the service and then run WCFServiceClient. The output from WCFServiceHost should look like the following:
The service is ready.
Press ENTER to terminate service.

Received Add(100,15.99)
Return: 115.99
Received Subtract(145,76.54)
Return: 68.46
Received Multiply(9,81.25)
Return: 731.25
Received Divide(22,7)
Return: 3.14285714285714


The output from WCFServiceClient should look like this:
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714

Press ENTER to terminate client.