How to Write a Simple Windows Communication Foundation Service and Client

Microsoft Corporation

 

Building the Service. 1

Building the Client 2

Creating a Configuration File for the Service. 3

Simplifying the Client Config. 4

Setting Up Logging. 4

Securing Communication Between the Client and Server 5

 

 

This article leads you through writing a “Hello, World” service and client with WCF.  It assumes that you’re running the WinFX January CTP on Visual Studio 2005 RTM.  (The Installation Guide explains how to install everything you need.)

 

We’ll build a service that simply returns the string “Hi!” when a client connects to it, and then build a client to interact with that service.  For simplicity, we’ll host both the service and the client inside console windows.  Let’s get started!

 

Building the Service

 

 

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

 

namespace HelloService

{

    class Program

    {

        static void Main(string[] args)

        {

 

            Uri baseURI = new Uri("");

ServiceHost HService = new

ServiceHost(typeof(HelloService), baseURI);

            HService.AddServiceEndpoint(typeof(HelloService),

                                   new BasicHttpBinding(), baseURI);

           

            HService.Open();

            Console.WriteLine("Service at your service.");

            Console.ReadKey();

            HService.Close();

 

        }

    }

 

    [ServiceContract]

    class HelloService

    {

        [OperationContract]

        string sayHi()

        {

            return ("Hi!");

 

        }

    }

}

 

·        And that’s it!  Just build and run, and you’ve got a working service.  You can even point a web browser at , and you’ll get a welcome page.

 

Building the Client

 

·        Now we’ve got a working service.  But in order to actually get information from that service, we need to use a client to connect to it.  Since this communication will often happen across different machines, we’ll pretend that the client and service know nothing about each others’ implementations.  Let’s do all the client work in a new instance of Visual Studio.

·        We’re going to host the client in a console window, so create a new Console Application

·        Add a reference to System.ServiceModel

·        The service we just built automatically exposes a lot of metadata that specifies how a client should communicate with it.  To build a client, we have to get that metadata from the service and use it to generate a proxy for the service inside the client itself.  That way, the client can make what look like local calls to its proxy;  the proxy then takes care of all the communication with the service. 

·        To get the metadata, we’ll use a tool called SvcUtil, which ships inside the Windows SDK.  Open up a Visual Studio Command Prompt and type: 

svcutil ?wsdl   

Then SvcUtil will go out to the WSDL file for the service, download the metadata, and generate the service proxy for you.  You’ll see that SvcUtil generates a couple of files—we’ll need to add those to our client solution.

·        Add the generated files to the HelloClient solution.  (I do this by running start . in my Command Prompt and dragging the files into the Solution Explorer.)

·        Rename output.config to app.config, which is the filename WCF will look for.  When you look at app.config, you can see that it contains information about the service endpoint as well as information about how to communicate with the service.  The other generated file, HelloService.cs, contains the proxy for HelloService which the client will use to communicate with the service.

·        Now just paste the following into Program.cs:

 

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

 

namespace HelloClient

{

    class Program

    {

        static void Main(string[] args)

        {

            HelloServiceProxy p = new HelloServiceProxy();

            Console.WriteLine(p.sayHi());

        }

    }

}

 

Just build and run, and you’ll be greeted with a working service and client.

 

Creating a Configuration File for the Service

 

 

//HService.AddServiceEndpoint(typeof(HelloService),

//                                new BasicHttpBinding(), baseURI);

 

·        add a new XML file to the solution and call it app.config.  Paste in the following code:

 

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>

    <services>

      <service type="HelloService.HelloService">

        <endpoint address=""

                  binding="basicHttpBinding"

                  contract="HelloService.HelloService" />

      </service>        

    </services>

  </system.serviceModel>

</configuration>

 

An added bonus:  if you’ve installed the Visual Studio Extensions for WinFX January CTP, you’ll get IntelliSense on this file, so you can easily write it from scratch.

·        So far, we haven’t actually changed anything about how the client and service communicate.  We’ve just moved the endpoint declaration from code into config.  We’ll need to rebuild the service, since we changed the code.  Start the service and the client, and you’ll see exactly the same behavior as before.

Simplifying the Client Config

 

·        Now let’s simplify the code in the client’s app.config file.  The config file we’re currently using is generated by SvcUtil, which makes its best guess as to what standard binding the service is using, and then sets more properties to ensure the client configuration matches the service configuration.  That leads to a complicated config file.  But we happen to know that the service is using basicHttpBinding, and so we can just alter the client to match that.

·        Alter the client’s app.config file so it file looks like this:

 

<?xml version="1.0" encoding="utf-8"?>

<configuration>

    <system.serviceModel>

        <client>

            <endpoint address=""

                binding="basicHttpBinding" contract="HelloService" />

        </client>       

    </system.serviceModel>

</configuration>

 

·        This time we haven’t touched the client code, so there’s no need to rebuild—just run the client.  Once again, the behavior hasn’t changed, since we haven’t actually changed anything about the client.

Setting Up Logging

 

·        Before we add security, let’s log the messages that are passed between the service and client so we can compare the difference with and without security.  We’ll use an SDK tool to set up the logging.

·        Open the SDK Command Window, and run SvcConfigEditor.exe (located at $root\Microsoft SDKs\Windows\v1.0\Bin\SvcConfigEditor.exe).  Open the service app.config file. 

·        Choose the “Diagnostics” tab, and select the “Logging” button to Edit the Message Logging element.

·        Choose to Create a WCF Message trace listener with standard properties by clicking the “Create…” button, and then choose where those messages will be logged.

·        Choose the “Logging” tab, and set both “LogEntireMessage” and “LogMessagesAtTransportLevel” to “true”

·        Save the changes.  The tool will inject more code into the service app.config that sets up and initializes the listeners.

·        Restart the service and the client, and shut down each of them.

·        View the logs by using the SvcTraceViewer.exe tool (located at $root\Microsoft SDKs\Windows\v1.0\Bin\SvcTraceViewer.exe).  Open the .e2e file that you logged messages to.

·        There are two messages logged, both of them in cleartext.  You can even see the result of the communication—sayHiResult in the second message contains the word “Hi!”.

Securing Communication Between the Client and Server

 

binding="basicHttpBinding"

to

binding="wsHttpBinding"

 

And that’s it!  You’ve built a WCF client and service, modified configurations, and even secured communication between them.