Microsoft & .NET .NET Windows Communication Foundation (WCF) Tutorial

Windows Communication Foundation (WCF) Tutorial

Introduction


Windows Communication Foundation (WCF) is a subset of the
.NET Framework that is designed to take interoperability in
distributed application environments to the next level. With
the emergence and acceptance of Web services and their
accompanying protocols and standards, development of
distributed applications has become a developer norm. WCF
simplifies that development by introducing a service-
oriented programming model that at its base provides
asynchronous and untyped message-passing. Extending from the
base are options and protocols designed to give the
developer choice in transport and encoding methods among
many other configurations.


Those familiar with .NET Remoting, .NET Web services and
Enterprises Services will recognize and have a familiar
development experience in WCF. In addition to the old
tricks, WCF enables serialization capabilities that allow
loose coupling and versioning of distributed application
across various platforms. This allows development of each
application in the environment to be performed more
independently and with fewer maintenance issues. Integration
with existing .NET Framework technologies such as COM+, Web
Services Enhancements (WSE), Message Queuing and others is
also provided within WCF.


Windows Communication Foundation comes with its own set
of terms and expressions. Before beginning it is important
to understand the following:



terms and expressions

Click here for larger image

The following link has additional WCF terms and
definitions: http://msdn.microsoft.com/en-
us/library/ms731079.aspx


Whether you are developing a Windows Communication
Foundation application to communicate across different
platforms, across the Internet, or just on the same server,
there are several tasks required to build a WCF application.
They are listed in order below:



  • Define the service contract

  • Implement the contract

  • Configure the service

  • Host the service

  • Consume the service via a client


The following walkthrough uses a console application to
host the service and a WPF client application to consume the
service. The WPF client application will retrieve a product
list from the service, display it to the user and allow the
user to delete individual products. To get started, create a
new console application in Visual Studio using the Console
Application template and name it
WCFProductService.


This walkthrough will use a class called
Product. Data will be created at runtime for
purposes of the example but a more likely scenario is that
you would communicate with a database to retrieve the
data.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WCFProductService
{
public class Product
{
public Product()
{ }

public int ProductID { get; set; }
public string ProductName { get; set; }
public string ProductDesc { get; set; }
public int Inventory { get; set; }

public List<Product> GenerateProductList()
{
List<Product> returnList = new List<Product>();

returnList.Add(new Product() { ProductID = 1, ProductName = “Ball”, ProductDesc = “White, Round”, Inventory = 10 });
returnList.Add(new Product() { ProductID = 2, ProductName = “Bat”, ProductDesc = “Wood”, Inventory = 7 });
returnList.Add(new Product() { ProductID = 3, ProductName = “Glove”, ProductDesc = “Brown, Leather”, Inventory = 3 });
returnList.Add(new Product() { ProductID = 4, ProductName = “Helmet”, ProductDesc = “Head Protection”, Inventory = 12 });
returnList.Add(new Product() { ProductID = 5, ProductName = “Pads”, ProductDesc = “Body Protection”, Inventory = 12 });
returnList.Add(new Product() { ProductID = 6, ProductName = “Jersey”, ProductDesc = “Team Spirit”, Inventory = 2 });
returnList.Add(new Product() { ProductID = 7, ProductName = “Foam Finger”, ProductDesc = “Awesome”, Inventory = 23 });
returnList.Add(new Product() { ProductID = 8, ProductName = “Tape”, ProductDesc = “Injury prevention”, Inventory = 102 });
returnList.Add(new Product() { ProductID = 9, ProductName = “Club”, ProductDesc = “9 Iron”, Inventory = 11 });
returnList.Add(new Product() { ProductID = 10, ProductName = “Bag”, ProductDesc = “Holds Clubs”, Inventory = 6 });

return returnList;
}
}
}


Product.cs


Defining the Service Contract


To create the service contract you will first have to add
a reference to System.ServiceModel.dll using
the Solution Explorer. Once the reference is added to the
project you will need to add the
System.ServiceModel namespace to the project by
adding the following using statement.



using System.ServiceModel;

Program.cs


Next define a new interface called
IProductManager and apply the
ServiceContract attribute to the interface.
For this example specify the Namespace value of the
attribute to “http://CompanyName.ProductManager”. It is best
practice to specify the namespace as it prevents the default
namespace value being added to the contract name. This
interface will be used later when implementing the service
contract.

In the IProductManager interface you will
then declare a method for each operation you wish to expose
via the contract. Add a method to retrieve the product list
and one to delete a product. Add the
OperationContract attribute to each method you
want to expose. When finished your interface should look
similar to the following.



// …

[ServiceContract(Namespace=”http://CompanyName.WCFProductService”)]
public interface IProductManager
{
[OperationContract]
List GetAllProducts();
[OperationContract]
void DeleteProduct(int n1);
}

// …


Program.cs

Implementing the Contract


After creating the contract via the interface above you
will then need to implement the interface. For this create
a class called ProductManagerService that
implements the IProductManager interface. Then
implement each method that was defined in the interface
within the ProductManagerService class. Your
code should look similar to the following when finished.



// …

public class ProductManagerService : IProductManager
{
public List<Product> GetAllProducts()
{
if (MasterProductList == null)
MasterProductList = new List<Product>();
if (MasterProductList.Count == 0)
MasterProductList = Product.GenerateProductList();

return MasterProductList;
}

public void DeleteProduct(int n1)
{
if (MasterProductList == null)
{
// throw and handle exception
}

var productToDelete = (from p in MasterProductList
where p.ProductID == n1
select p).FirstOrDefault();

MasterProductList.Remove(productToDelete);
}
}
// …


Program.cs

Configuring the Service


After the service contract has been implemented you are
now ready to configure the service. Configuring the service
involves determining and then defining how the service will
be exposed, the location where it will be found, the type of
security and message encoding used to send and receive
messages. Windows Communication Foundation provides an
abundance of options when performing configuration.


There are two basic ways to set the configuration for the
service. The first option is to use inline code which the
walkthrough uses for configuration. The second option uses
configuration files and takes full advantage of the .NET
Framework’s configuration technology. When the WCF service
is hosted in IIS for example the configuration would be part
of the Web.config file.


For those looking to gain efficiency through reuse, WCF
includes common configurations in the form of bindings that
allow you to quickly set up the more basic features.
Bindings can be used either inline or through XML elements
in configuration files. In the walkthrough,
WCFProductService uses the
BasicHttpBinding binding in code to configure
the service. The BasicHttpBinding does not
provide security by default so therefore should only be used
in secured network environments or with added security. A
full list of WCF provided bindings and details to make a
determination on which binding would work best for your
situation can be found at http://msdn.microsoft.com/en-
us/library/ms730879.aspx
.


Within the Main method add a
BasicHttpBinding object with the following
properties.




BasicHttpBinding binding = new BasicHttpBinding();
binding.MessageEncoding = WSMessageEncoding.Text;
binding.Security.Mode = BasicHttpSecurityMode.None; // default

Program.cs


There are many additional properties on the object that
configure various different aspects of the service. Take
some time to get familiar with the options as not all need
to be configured but are useful to know when determining the
best configuration for your service.


The next configuration step is for the endpoints.
Endpoints are where WCF services are ‘found’ and where you
go to gather information about the WCF service. The
contract, configuration information and the address come
together to comprise an endpoint. The contract and
configuration has already been coded leaving the address, or
endpoint location, to be implemented.


In the Main method create a new Uri object for the
service’s base address.



Uri address = new Uri(“http://localhost:8000/WCFProductService”);

Program.cs


The last configuration required is to make the service
discoverable through metadata. In the
System.ServiceModel.Description namespace there
is a class called ServiceMetadataBehavior that
allows you to configure your WCF service to publish metadata
about itself when requested. For those familiar with ASP.NET
Web services this would be similar to discovery and
generating the WSDL and adding a Web Reference to your
project. Instead now you are making a service discoverable
so a Web Service proxy can be created on your client as you
will see later in this article.


To enable metadata discovery first add a using reference
to System.ServiceModel.Description. Next create
a new ServiceMetadataBehavior object in the
Main method and set its HttpGetEnabled property
to true. In the next step you will add the behavior to the
ServiceHost object.




using System.ServiceModel.Description;

// …

ServiceMetadataBehavior smdb = new ServiceMetadataBehavior();
smdb.HttpGetEnabled = true;


Program.cs


Note that by default metadata publishing is disabled due
to security concerns with overexposing your service’s
surface to attack. Alternatives exist that do not require
you to publish the service’s metadata. Using the
ServiceModel Metadata Utility Tool (discussed later) you are
still able to generate metadata and client code directly
from your service assemblies.


Hosting the Service


Now that the service has been defined, implemented and
configured it is time to create the service host object to
host the service and expose the service via an endpoint. The
first step is to create a new ServiceHost
object to host the WCF service. Use the base address Uri
object created in the previous step and for the
implementation of the service contract use
ProductManagerService.


Next add a service endpoint to the
ServiceHost object. For parameters pass in the
interface that is to be exposed
(IProductManager), the previously created
binding object and the endpoint’s address. Note that the
address used here is relative to the base address used by
the ServiceHost object. Then, before starting
the service, add the ServiceMetadataBehavior
object created in the previous step to the
ServiceHost object’s
Description.Behaviors collection.


The Open() method of the
ServiceHost object tells the service to start
waiting for incoming messages and the Close()
method stops the service. When finished your Main method in
Program.cs should look similar to the
following.



// …

static void Main(string[] args)
{
BasicHttpBinding binding = new BasicHttpBinding();
binding.MessageEncoding = WSMessageEncoding.Text;
binding.Security.Mode = BasicHttpSecurityMode.None; // default

Uri address = new Uri(“http://localhost:8000/WCFProductService”);

ServiceHost productServiceHost = new
ServiceHost(typeof(ProductManagerService), address);

productServiceHost.AddServiceEndpoint(typeof(IProductManager),
binding, “ProductManager”);

ServiceMetadataBehavior smdb = new ServiceMetadataBehavior();
smdb.HttpGetEnabled = true;

try
{
productServiceHost.Description.Behaviors.Add(smdb);

productServiceHost.Open();
Console.WriteLine(“ProductManager Service is open!”);
Console.ReadLine();

productServiceHost.Close();
}
catch (CommunicationException ce)
{
// handle/log exception, clean up ServiceHost…
productServiceHost.Abort();
}
}

// …


Program.cs


Before moving on, take a minute to familiarize yourself
with all the different options available in creating the
ServiceHost object and adding the endpoint. One
of the great benefits of Windows Communication Foundation is
how many options you have and how configurable it is. At the
same time it can also be a source of overwhelming confusion
if you have not taken the time to understand all of what is
available.


To test that the service is working run the console
application from Visual Studio (for Vista and Windows 7
users make sure you are running VS as an administrator) and
open IE to the service’s debug page located at http://
localhost:8000/WCFProductService
.

Note: If you are running Windows 7 you may need to run
the following command from an administrator command prompt
to view the page in IE.



netsh http add urlacl url=http://+:8000/WCFProductService user=[username]

Administrative Command Prompt command

Building a WCF client


The final major step in this walkthrough is to create a client to consume the Windows Communication Foundation service that has just been created. The walkthrough will create the client using Windows Presentation Foundation (WPF but it is important to note that the client could be an ASP.NET Web Application, Java application or even another WCF service. The type of client is less important due to WCF’s service oriented architecture that abstracts away the communication nightmare that once existed when integrating between multiple systems and platforms.


Open another instance of Visual Studio and create a new WPF project named WCFProductClient. If you are unfamiliar with WPF and feel more comfortable with Windows Forms or Console applications, those are both acceptable alternatives. On the main window create a ListBox control to display the product list data and add a button to delete the selected product from the list. Then create the event handlers for the Window loaded event and the button click event.


Now you will need to generate the proxy that will access the WCF service. There are 2 primary ways this can be accomplished and both yield the same results. The first is to use the Add Service Reference wizard within Visual Studio and the second is to use the ServiceModel Metadata Utility Tool (Svcutil.exe) provided by WCF. If you have the luxury of building a .NET based client and the WCF service publishes metadata as shown in the example above then using the Visual Studio wizard is the quickest and easiest method to generate the proxy. Other cases where the WCF service does not publish metadata then the ServiceModel Metadata Utility Tool will be used to generate the proxy.


The following two examples will walkthrough both methods of generating the proxy. Before using either method make sure to have the WCF service running.


Using the Visual Studio wizard, start by right-clicking on the References folder in the Solution Explorer and selecting the Add Service Reference option. Enter the WCF service’s base address and click Go. The wizard will discover the service, exposed endpoints and the operations that those endpoints allow.

Visual Studio Add Service Reference Wizard

Enter the Namespace you want to use for the proxy and select OK. Visual Studio will then generate the proxy and add all necessary references in the client project. When finished the client project will be setup to start using the WCF service without further configuration.


Using the ServiceModel Metadata Utility Tool, start by opening a Windows SDK console and navigate to the directory where you want to place the generated proxy code. Using the appropriate switches create the proxy with the following command. Once generated use Visual Studio to add the files to the client project by right-clicking on the solution and selecting Add, Existing Item.


  Svcutil.exe /language:cs /out:ProductManagerService.cs /config:app.config http://localhost:8000/WCFProductService

ServiceModel Metadata Utility Tool command


Regardless of the method used to generate the proxy, once generated it is very easy to configure and consume the WCF service. Using the two events, Windows Loaded and the Button Click, add the following WCF client code.


  private void Window_Loaded(object sender, RoutedEventArgs e)
{
ServiceReferenceProductManager.ProductManagerClient pmc = new WCFProductClient.ServiceReferenceProductManager.ProductManagerClient();

lstProducts.ItemsSource = pmc.GetAllProducts();

pmc.Close();
}

private void btnDeleteProduct_Click(object sender, RoutedEventArgs e)
{
ServiceReferenceProductManager.Product selectedProduct = (ServiceReferenceProductManager.Product)lstProducts.SelectedItem;

ServiceReferenceProductManager.ProductManagerClient pmc = new WCFProductClient.ServiceReferenceProductManager.ProductManagerClient();
pmc.DeleteProduct(selectedProduct.ProductID);

lstProducts.ItemsSource = pmc.GetAllProducts();

pmc.Close();
}


Window1.xaml.cs


This code populates the ListBox with the product list pulled from the WCF service and allows the user to delete the selected product.


Conclusion


You have just walked through creating a Windows Communication Foundation service by defining a service contract, implementing the contract, configuring and hosting the service then finally consuming the service via a WCF client.


About the Author


Matt Goebel is the Founder and President of AP Innovation, Inc. in Indianapolis, Indiana. He can be reached at 859-802-7591 or matt [email protected].

Latest Posts

Related Stories