Clients can easily consume WCF services by adding a
service reference directly from Visual Studio 2010. In the next example
you create a simple Console client application for validating ISBNs by
invoking objects from the WCF service implemented in the previous
section.
Creating the Client and Adding a Service Reference
Add a new Console project to the current solution and name it BookClient.
The first step you have to accomplish is adding a service reference to
the WCF service. Right-click the new project name in Solution Explorer
and select Add Service Reference. This brings up the Add Service Reference
dialog where you need to enter the full Web address of your service. If
the service you want to add a reference to is available in the current
solution, as in the current example, simply click Discover. The service appears in the dialog, as shown in Figure 1.
Click the service name on the
left to allow the development server to correctly host the service and
discover its members. At this point the dialog lists available contracts
(IBookService in this case) and their members. Replace the Namespace identifier with BookServiceReference.
Understanding the Proxy Class
The WCF service is
exposed through the network via a WSDL. To consume objects and data
exposed by the WSDL, the client needs a proxy class that is responsible
for translating WSDL information into managed code that you can reuse.
This is accomplished via a command-line tool named SvcUtil.exe that is
part of the .NET Framework. Fortunately you do not need to run SvcUtil
manually because Visual Studio will do the work for you. When you click OK from the Add Service Reference
dialog, Visual Studio invokes SvcUtil and generates a proxy class. You
notice, in Solution Explorer, a new folder named Service references. This folder contains all service references and, for the current example, it stores a new item named BookServiceReference. This new item provides all metadata information required to consume the service and especially the proxy class. Click the Show All Files button in Solution Explorer and expand the Reference.svcmap file; then double-click the Reference.vb file. This code file exposes the BookServiceReference
namespace to provide client-side code for accessing members exposed
from the service. Particularly this namespace exposed client-side
implementations of the Book class and the IBookService interface. The most important class exposed by the namespace is named BookServiceClient and is the actual proxy class, which inherits from System.ServiceModel.ClientBase,
and which is responsible for connecting to the service and for closing
the connection other than exposing service members such as the ValidateBook that was implemented on the service side. The namespace also exposes the IBookServiceChannel interface that inherits from IClientChannel,
which provides members for the request/reply infrastructure required by
WCF services. You instantiate the proxy class to establish a connection
with the WCF service, and you interact with the proxy class for
accessing members from the service, as explained in next section.
Invoking Members from the Service
To invoke service members, you need to create an instance of the proxy class, which in our example is named BookClient.BookServiceReference.BookServiceClient.
Creating an instance of the class can establish a connection to the WCF
service and give you access to public members. Continuing with the
previous example, the client application could have an instance of the Book class and invoking the ValidateBook method for checking if the Book instance is correct according to our needs. Code in Listing 1 shows how to accomplish this.
Listing 1. Instantiating the Proxy Class and Invoking Service Members
Imports BookClient.BookServiceReference
Module Module1
Sub Main() 'Creates an instance of the proxy class 'and automatically establishes a connection 'to the service Dim client As New BookServiceClient
'A new book 'Note that the RegEx pattern requires to write the ISBN in the form 'provided below, so like: 000-0-0000-0000-0 including the minus 'character Dim myBook As New Book With myBook .Author = "Alessandro Del Sole"
.Title = "VB 2010 Unleashed" .ISBN = "978-0-6723-3100-8 "
.DatePublished = Date.Today End With
'Invokes the ValidateBook method from 'the service Console.WriteLine(client.ValidateBook(myBook)) Console.WriteLine("Done") Console.ReadLine() client.Close()
End Sub End Module
|
Therefore in the client you can invoke all public members from the service, where public means functions decorated with the OperationContract attribute and data classes decorated with the DataContract attribute. Running the code in Listing 2 produces the result shown in Figure 2, but you can try to change the ISBN code to check how the application works with different values.
Remember to close the connection to the service invoking the Close method on the proxy class. This ensures that the service will be shut down.
Understanding the Configuration File
When you add a proxy class
to your WCF service, Visual Studio also updates the configuration file
to provide information on how to reach and interact with the service.
The most important information is stored in the System.ServiceModel section of the app.config file. Listing 2 shows the most interesting excerpt.
Listing 2. Configuration Settings for the Client
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IBookService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:5529/BookService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IBookService" contract="BookServiceReference.IBookService" name="BasicHttpBinding_IBookService" /> </client> </system.serviceModel>
|
Substantially
the app.config file maps the related nodes in the Web.config file from
the service. This is important to remember in case you want to implement
a custom configuration different from the default one. The bindings node defines how data and information are transferred. The basicHttpBinding
binding is the simplest way and uses Http protocol and Text or Xml as
the encoding format. WCF offers lots of other bindings specific for
particular needs, such as secured communications or peer-to-peer
applications. Table 1 summarizes built-in bindings.
Table 1. WCF Built-In Bindings
Binding | Description |
---|
BasicHttpBinding | Used for ASP.NET-based Web services. It uses the HTTP protocol and text or XML for messages encoding. |
WSHttpBinding | Used for secured communications in nonduplex service contracts. |
WSDualHttpBinding | Used for secured communications in duplex service contracts including SOAP. |
WSFederationHttpBinding | Used
for secured communications according to the WS-Federation protocol that
provides an easy authentication and authorization system within a
federation. |
NetTcpBinding | Used for secured communications between WCF applications distributed across multiple machines. |
NetNamedPipeBinding | Used for secured communications between WCF applications on a same machine. |
NetMsmqBinding | Used for messaging communications between WCF applications. |
NetPeerTcpBinding | Used for peer-to-peer applications. |
MsmqIntegrationBinding | Used for communications between WCF applications and MSMQ applications across multiple machines. |
BasicHttpContextBinding | Similar to BasicHttpBinding but with the capability of enabling cookies. |
NetTcpContextBinding | Used for communications between WCF applications that need to use SOAP headers for data exchange across multiple machines. |
WebHttpBinding | Used for WCF services exposed via endpoints requiring HTTP requests instead of SOAP endpoints. |
WSHttpContextBinding | Similar to WsHttpBinding with the ability of enabling SOAP headers for information exchange. |
Notice how you can customize timeouts (closeTimeout, openTimeout, sendTimeout, and receiveTimeOut) and other interesting options such as maxBufferSize and maxReceivedMessageSize.
These two are important because you might be required to increase the
default size in case your application transfers big amounts of data. Now
take a look at the client node. This
defines the endpoint’s ABC, such as the address pointing to the physical
URI of the service, the contract interface (BookServiceReference.IBookService),
and the binding transport protocol. Notice that when moving the service
to production, the address URI must be replaced with the
Internet/intranet address of your service. This can be accomplished by
simply replacing the address item in the configuration file without the need of rebuilding the application.