from another class that isn ’ t decorated with the DataContract attribute, you will receive an
error when you attempt to run the service. Therefore, you must either also decorate the inherited
class with the data contract attributes, or remove the data contract attributes from the data class
(although this is not recommended) so the data contract is inferred instead.
If you choose to have inferred data contracts and not decorate the data classes with the data
contract attributes, all public properties will be serialized. You can, however, exclude properties
from being serialized if you need to by decorating them with the IgnoreDataMember attribute.
A caveat of inferred data contracts is that the data classes must have a default constructor (that is,
one with no parameters), or have no constructors at all (in which case a default constructor will
be created for it by the compiler). If you do not have a default constructor in a data class with an
inferred contract, you will receive an error when you attempt to run the service. Note that when an
object of that type is passed in as an operation ’ s parameter, the default constructor will be called
when the object is created, and any code in that constructor will be executed.
Although it ’ s not strictly required, it ’ s best that you keep your data contract
classes separate from your other application classes, and that you use them only
for passing data in and out of services (as data transfer objects, aka DTOs). This
way you minimize the dependencies between your application and the services
that it exposes or calls.
Defi ning Contracts . 687
688 .
chaPter 31 WindoWS communicATion FoundATion (WcF)
confiGurinG wcf serVice endPoints
A WCF service has three main components: the Address, the Binding, and the Contract (easily
remembered by the mnemonic ABC):
.
The address specifies the location where the service can be found (the where) in the form of
a URL.
.
The binding specifies the protocol and encoding used for the communication (the how).
.
The contract details the capabilities and features of the service (the what).
The configurations of each of these components combine to form an endpoint. Each combination of
these components forms a separate endpoint, although it may be easier to consider it as each service
having multiple endpoints (that is, address/binding combinations). What makes WCF so powerful is
that it abstracts these components away from the implementation of the service, enabling them to be
configured according to which technologies the service will support.
With this power, however, comes complexity, and the configuration of endpoints can become rather
complex. In particular, many different types of bindings are supported, each having a huge number
of options. However, WCF 4.0 simplifies this configuration over previous versions by providing
default endpoints, standard endpoints, default protocol mappings, default binding configurations,
and default behavior configurations — all of which ease the amount of configuration required.
Because endpoint configuration can become very complex, this chapter focuses on just the most
common requirements.
Endpoints for the service are defined in the App.config file. Though you can open the App.config file
and edit it directly, Visual Studio comes with a configuration editor tool to simplify the configuration
process. Right-click the App.config
file in the Solution Explorer, and select Edit WCF Configuration
from the context menu. This opens the Microsoft Service Configuration Editor, as shown in Figure 31-2.
fiGure 31-2
Configuring WCf service endpoints .
689
The node you are most interested in is the Services node. Selecting this node displays a summary
in the Services pane of all the services that have been configured and their corresponding endpoints.
You will find that a service is already listed here, although it is the configuration for the default
service that was created by the project template (Service1), which no longer exists. Therefore, you
can delete this service from the configuration and start anew (click the service and press Delete).
If you try running the service (detailed in the next section) without properly
configuring an endpoint for it (or have an incorrect name for the service in
the configuration), you will receive an error stating that the WCF Service Host
cannot find any service metadata. If you receive this error, ensure that the
service name (including its namespace) in the configuration matches its name in
the actual service implementation.
The first step is to define your service in the configuration. From the Tasks pane, click the Create a
New Service hyperlink. This starts the New Service Element Wizard. In the service type field you
can directly type the qualified name of your
service (that is, include its namespace), or click
the Browse button to discover the services
available (it’s best to use the Browse function
because this automatically fills in the next step
for you). If you use this option you must have
compiled your project first, and then you can
navigate down into the bin\Debug folder to find
the assembly, and drill through it to display
the services within that assembly (as shown in
Figure 31-3). Now you have specified the service
implementation, but next you need to specify
the contract, binding, and address for the
endpoint.
If you used the Browse button in the previous
step (recommended), this next step (specifying
the service contract) will have already been
filled in for you (as shown in Figure 31-4).
Otherwise, fill this in now.
The next step states that it allows you to
either create a new binding configuration,
or use an existing binding configuration (as
shown in Figure 31-5). However, the first
option is probably a bit misleading, because
it doesn’t create a new binding configuration
but instead helps you (via a wizard) choose
which of the default binding configurations
you want to use for the endpoint. Each
fiGure 31-3
fiGure 31-4
690 .
chaPter 31 WindoWS communicATion FoundATion (WcF)
binding has a default/standard binding
configuration, but additional configurations
can be created for a binding (under the
Bindings node in the Configuration tree)
that enable you to configure exactly how
a binding behaves. The custom bindings
configuration can become rather complex,
with a myriad of options available. However,
in many cases you will find that you will
just need a default binding (unless you
actually have a specific need to change
its behavior). In this chapter, assume that
the default bindings are satisfactory for
your needs.
So the actual options you have on this screen
(in spite of the text displayed) are to either
run another part of the wizard that will help you decide which of the default binding configurations
you want (the first option), or to simply choose from a list of the existing binding configurations
(that is, both the default and custom binding configurations) if you know which one you want (the
second option).
Choosing which binding you should use really depends on your usage scenario for the service.
The wizard will help you choose a binding, with a description under each option detailing
the purpose for the option. You must remember, however, that not all clients may support the
binding you choose — therefore, you must also consider what clients will be using your service
and choose the binding accordingly. Of course, you can add additional endpoints with different
bindings to support each type of client. The most common bindings are basicHttpBinding
and wsHttpBinding — with both communicating over HTTP. The basicHttpBinding binding
is used to communicate in the same manner as the ASMX web services (which conform to
the WS-I Basic Profile 1.1). The wsHttpBinding binding implements a number of additional
specifications other than the basicHttpBinding binding (including reliability and security
specifications), and additional capabilities such as supporting transactions. However, older
.NET clients (pre-.NET Framework 3.0), non-.NET clients, mobile clients, and Silverlight
clients will not be able to access the service using this binding. For this example, choose the
wsHttpBinding binding.
The final step is to specify the address for the endpoint. You can specify the entire address to be
used by starting the address with a protocol (such as http://), or specify a relative address to
the base address (discussed shortly) by just entering a name. In this case, delete the default entry
and leave it blank — this endpoint will simply use the base address that you are about to set up.
A warning will be displayed when moving on from this step, but it can be safely ignored.
A summary is shown of the endpoint configuration, and you can finish the wizard. This wizard
has allowed you to create a single endpoint for the service, but chances are you will need
to implement multiple endpoints. You can do this easily by using the New Service Endpoint
fiGure 31-5
Hosting WCf services .
691
Element Wizard to create additional endpoints. Underneath the service node that was created
will be an Endpoints node. Select this, and then click the Create a New Service Endpoint
hyperlink in the Tasks pane. This opens the wizard that will help you to create a new endpoint.
As was mentioned earlier you now need to configure a base address for the endpoint. Because you
chose to use the wsHttpBinding binding you will use a standard http URL that you will make the service
accessible by. Under the newly created service node is a Host node. Select this, and from the Host pane
that appears click the New button to add a new base address to the list (which is currently empty).
A dialog appears asking for the base address, and contains a default entry. The address you enter
here will largely depend on the binding that was selected earlier. Because you chose one of the HTTP
bindings, use http://localhost:8733/Chapter31Sample as the base address (port 8733 was
chosen at random) for this example.
Your service is now configured with the endpoints that it will support. There is another topic
related to service configuration that is worth touching upon — that of behaviors. In essence, WCF
behaviors modify the execution of a service or an endpoint. You will find that a service behavior
containing two element extensions has already been configured for the service by the project
template. If you expand the Advanced node and select the Service Behaviors node under it, you
will find a behavior has been defined containing the serviceMetadata and serviceDebug element
extensions. The serviceMetadata behavior element extension enables metadata for the service to
be published. Your service must publish metadata in order for it to be discoverable and able to be
added as a service reference for a client project (that is, create a proxy). You could set this up as
a separate endpoint with the mexHttpBinding binding, but this behavior will merge this binding
with the service without requiring it to be explicitly configured on the service itself. This makes it
easy to ensure all your services are discoverable. Clicking the serviceMetadata node in the tree will
show all its properties — ensure that the HttpGetEnabled and the HttpsGetEnabled properties are
set to True. The other behavior element is the serviceDebug behavior extension. When debugging
your service it can be useful for a help page to be displayed in the browser when you navigate to
it (essentially publishing its WSDL at the HTTP get URL). You can do this by setting both the
HttpHelpPageEnabled and HttpsHelpPageEnabled properties to True. Another useful property
to set to true while debugging is the IncludeExceptionDetailsInFaults property, enabling you to
view a stack trace of what exception occurred in the service from the client. Although this behavior
is very useful in debugging, it’s recommended that you remove it before deploying your service (for
security purposes).
hostinG wcf serVices
With these changes made you can now build and run the WCF
Service Library. Unlike a standard class library, a WCF Service
Library can be “run” because Visual Studio 2010 ships with the
WCF Service Host utility. This is an application that can be used to
host WCF services for the purpose of debugging them. Figure 31-6
fiGure 31-6
shows this utility appearing in the taskbar.
692 .
chaPter 31 WindoWS communicATion FoundATion (WcF)
As the balloon in Figure 31-6 indicates, clicking the balloon or the taskbar icon brings up a dialog
showing more information about the service that is running. If the service doesn’t start correctly,
this dialog can help you work out what is going wrong.
If you aren’t running under elevated privileges, you may end up with an error
from the WCF Service Host relating to the registration of the URL you specified
in the configuration file. The issue is a result of security policies on the computer
that are preventing the WCF Service Host from registering the URL you have
specified. If you receive this error you can resolve it by executing the following
command using an elevated permissions command prompt (that is, while
running as administrator), replacing the parameters according to the address of
the service and your Windows username.
netsh http add urlacl url=http://+:8733/Chapter31Sample
user= < username >
This command will allow the specified user to register URLs that match the
URL prefix. Now when you try to run your WCF Service Library again it should
start successfully.
In addition to hosting your WCF service, Visual Studio 2010 also launches the WCF Test Client
utility as you can see in Figure 31-7. This utility automatically detects the running services, and
provides a simple tree representation of the services and their corresponding operations.
fiGure 31-7
Hosting WCf services .
693
When you double-click a service operation you will see the tab on the right-hand side of the dialog