Client Development

Description Article
Table of Contents
Description

The WCF services can be consumed through:

  • Using an HttpWebRequest to invoke the service through the correspondent URL of the endpoint; or
  • Creating a WCF client appication.
Operations
WCF Client: Definition
How to do it

WCF client objects are used by Client applications to invoke and consume service operations.

An WCF Client is managed code representing a proxy to the WCF service and it will be used to invoke the WCF service. Therefore it can only be used in an managed application that uses a WCF to communicate.

A service proxy enables the use of the services in an object-oriented way:

  • Proxy classes abstracts the communication model used by the service;
  • Proxy classes implement the service interface of the service and enable the Client to call methods on the service interface as if these are local methods.

Consuming a WCF service using a Client application consists in:

  1. Obtain the service contract, bindings, and address information for a service endpoint;
  2. Instantiate the WCF client using that information;
  3. Call operations;
  4. Close the WCF client object.

How it works

  1. WCF client types implement the target service contract, so when creating one and configure it, the client object directly to invoke service operations;
  2. The WCF run time converts the method calls into messages, sends them to the service, listens for the reply, and returns those values to the WCF client object as return values or out or ref parameters.

How to use it

Once the client object is created and configured, an operation can be called as if they are local:

  1. Open communication channel and call operations: when the client application calls the first operation, WCF automatically opens the underlying communication channel, OR alternatively, the programmer can explicitly open and close the channel prior to or subsequent to calling other operations.
  2. Close the WCF client object: the underlying channel is closed when the object is dsposed.

Note: The opening, calling, and closing of the WCF client object should occurs within a single try/catch block

TestServiceClient wcfClient = new TestServiceClient();

try
{
    Console.WriteLine(wcfClient.Add(4, 6));
    wcfClient.Close();
}
catch (TimeoutException timeout)
{
    // Handle the timeout exception.
    wcfClient.Abort();
}
catch (CommunicationException commException)
{
    // Handle the communication exception.
    wcfClient.Abort();
}
Consuming Service: Generate a WCF Client using the SvcUtil.exe tool
How to do it

This type of WCF client is automatically created by the “SvcUtil.exe” utility that generates a derived class of the ClientBase<TChannel> class defined on the System.ServiceModel namespace.

This class encapsulates a client channel implementation (i.e. a proxy class) that is dynamically constructed by the ChannelFactory<TChannel> class.

The proxy can be generated through the Add Service Reference feature of Visual Studio. This is a menu option that works as a wrapper around the “SvcUtil.exe” utility, spawning a process with the necessary parameters, namelly the Uri of the service.

The output will be the:

  • A proxy implementation class: file will be added to the project; and
  • A configuration file with the WCF runtime configuration settings: this file contents will be merged into the current application configuration file (if any).

Alternativelly the spawned process can be manually and explicitly initiated at command-line by calling directly the ”SvcUtil.exe” utility:

svcutil /language:vb /out:ClientCode.vb /config:app.config http://computerName/Training/Service1.svc?wsdl
svcutil /language:vb /out:ClientCode.vb /config:app.config http://computerName/Training/Service1.svc/mex

Requirements

  • The “SvcUtil.exe” utility requires configuration of the metadata exchange endpoint:
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

or the HTTP-GET address active on the service behavior:

<serviceMetadata httpGetEnabled="true"/>
  • The service host must be running
Consuming Service: Generate manually a WCF Client through implementation of the ClientBase<T> class

Extending the ClientBase class it is possible to manually create a proxy class to be used at client side instead of using the Visual Studio option Update Service Reference. When done manually:

  • The custom class will inherit from the ClientBase class and pass as the generic argument the service contract to use;
  • The result of this generic-oriented inheritance is that the ClientBase class’s Channel property adopts all the operations of the indicated service contract;
  • No configuration settings are merged with the project configuration file (if exists)

How to do it
public partial class TestServiceClient : System.ServiceModel.ClientBase<ITestService>, ITestService
{

    public TestServiceClient()
    {
    }

    public TestServiceClient(string endpointConfigurationName) :
            base(endpointConfigurationName)
    {
    }

    public TestServiceClient(string endpointConfigurationName, string remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public TestServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public TestServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(binding, remoteAddress)
    {
    }

    public string TestService1(string msg)
    {
        return base.Channel.TestService1(msg);
    }
}
Consuming Service: Generate manually a WCF Client through the use of the ChannelFactory<T> class

The ChannelFactory is a factory for creating service communication channels at runtime. The class is used to construct a channel between the client and the service without the need of a proxy. This means no matter how often the service contracts change, the proxy classes won’t have to manually be re-generated nor the client-side service model configuration be altered each time.

The ChannelFactory handles a given service contract type passed as the generic argument of the class and the address and binding of the endpoint must be explicitly configured by using the address, binding, and contract objects.

Remarks

This option must or should be used when:

  • No configuration exists on the configuration file and must be provided at run time due to some parameterization (e.g. if A then use wsHttpBinding else use NamedPipesBinding);
  • Assembly-sharing scenarios when both ends know about the contract interface. In this case it will be redundant to run the SvcUtil.exe tool;
  • When adding behaviors programmatically, the behavior is added to the appropriate Behaviors property on the ChannelFactory prior to the creation of any channel;
  • The service implements more than one contract: It can directly create a channel reuse given the specific contract. If Visual Studio was used then it would generate duplicated proxy types at client
How to do it
// Create a new EndpointAddress object.
EndpointAddress address
   = new EndpointAddress("http://localhost:8000/Training/TestService1");

// Create a new binding object.
BasicHttpBinding binding = new BasicHttpBinding();

// Create a proxy object using the contract, binding, and address objects.
IService proxy = ChannelFactory<IService>.CreateChannel(binding, address);

Note: Once a call to the CreateChannel method (or System.ServiceModel.ClientBase.Open, System.ServiceModel.ClientBase.CreateChannel, or any operation on a WCF client object), the channel factory cannot be modified and expect to get channels to different service instances, even if only the target endpoint address changed:  In case of new configuration  a new channel factory must be created first.