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

WCF: Real Easy

5.00/5 (2 votes)
9 Jul 2013CPOL3 min read 7.9K  
How to use WCF for communicating between .NET processes and how to use it for HTTP requests.

If you search for WCF tutorials, you’ll find a lot of elaborate examples that involve editing several files.

This tutorial is (supposed to be) different. It uses the simple most approach I could find for using WCF. It’ll only involve one file and no XML descriptors (read: app.config).

I’ll explain how to use WCF for communicating between .NET processes and how to use it for HTTP requests.

The initial code is based primarily on this nice tutorial.

Let’s get started.

Preparation

For this tutorial, simply create a console application project.

You need to target at least .NET 3.5.

You also need to add references to System.ServiceModel and (for later) System.ServiceModel.Web.

In your Program.cs, we will use the following usings:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Threading;

You can remove everything else in this file – except for the namespace.

The Service Interface

The first thing we need is a service interface (also called “service contract”).

Add the following code to your Program.cs:

[ServiceContract]
public interface IService {
  // Returns "Hello, name" to the user.
  [OperationContract]
  string Ping(string name);
}

This interface will be implemented on the server side and used on the client side. So usually you’ll place it in a shared project.

The Service Implementation

Next, we’re going to implement this interface on the server side.

Add the following code to your Program.cs:

// Implementation of IService
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class ServiceImplementation : IService {
  public string Ping(string name) {
    Console.WriteLine("SERVER - Processing Ping('{0}')", name);
    return "Hello, " + name;
  }
}

The setting InstanceContextMode.PerCall will create a new instance of ServiceImplementation for every call. Of course, other settings are possible as well.

The Server

For the service to be able to respond to request, it needs to be executed in a so called service host.

Add the following code to your Program.cs:

class Server {
  private readonly ManualResetEvent m_stopFlag = new ManualResetEvent(false);
  private readonly Thread m_serverThread;

  public Server() {
    this.m_serverThread = new Thread(this.Run);
    this.m_serverThread.IsBackground = true;
  }

  public void Start() {
    this.m_serverThread.Start();
    Thread.Sleep(1000); // wait for server to start up
  }

  public void Stop() {
    this.m_stopFlag.Set();
    this.m_serverThread.Join();
  }

  private void Run() {
    var svh = new ServiceHost(typeof (ServiceImplementation));
    svh.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), "net.tcp://localhost:8000");
    svh.Open();

    Console.WriteLine("SERVER - Running...");
    this.m_stopFlag.WaitOne();

    Console.WriteLine("SERVER - Shutting down...");
    svh.Close();

    Console.WriteLine("SERVER - Shut down!");
  }
}

The important code here is in Run().

First, we create an instance of ServiceHost and pass the service implementation to it.

Next, we add an endpoint for the host (i.e. where the client will connect to). Here we specified the service interface because the service implementation could implement multiple services.

Last, we start the service host with Open().

The Client

Only one thing remains: the client.

Add the following code to your Program.cs:

internal class Program {
  private static void Main() {
    Console.WriteLine("WCF Simple Demo");

    // start server
    var server = new Server();
    server.Start();

    // run client
    using (var scf = new ChannelFactory<IService>(new NetTcpBinding(), "net.tcp://localhost:8000")) {
      IService s = scf.CreateChannel();

      while (true) {
        Console.Write("CLIENT - Name: ");

        string name = Console.ReadLine();
        if (string.IsNullOrEmpty(name)) {
          break;
        }

        string response = s.Ping(name);
        Console.WriteLine("CLIENT - Response from service: " + response);
      }

      ((ICommunicationObject)s).Close();
    }

    // shutdown server
    server.Stop();
  }
}

A couple of things are happening here.

First, we create and start the server. It runs on a different thread.

Then, we open a channel to our service by using ChannelFactory and CreateChannel().

The instance returned by CreateChannel() can then be used to communicate with the server.

WCF HTTP Service

It’s also easy to accept HTTP requests with WCF.

First, you need to add [WebGet] (GET) or [WebInvoke] (POST) to the methods of IService you want to be “web-callable”.

For example, change the implementation of IService to this:

[ServiceContract]
public interface IService {
  // Returns "Hello, name" to the user.
  [WebGet(ResponseFormat = WebMessageFormat.Json)]
  [OperationContract]
  string Ping(string name);
}

Note the added [WebGet] attribute. We also specified that the return value will be converted to JSON. The default is to return it as XML.

We don’t need to change ServiceImplementation at all.

So, next we’ll modify Server.Run(). Add the following code just after svh.Open();

var wsh = new WebServiceHost(typeof(ServiceImplementation), new Uri("http://localhost:8080"));
wsh.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");

// Define debug properties
ServiceDebugBehavior sdb = wsh.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.HttpHelpPageEnabled = false;
sdb.IncludeExceptionDetailInFaults = true;

wsh.Open();

You just need to create a WebServiceHost – similar to how you created the ServiceHost before.

Note that svh and wsh use different ports.

After starting the app, you can call Ping() by going to:

Download Code

You can get the complete code here: Program.cs.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)