You are on page 1of 14

WCF – IMPORTANT QUESTIONS

ASKED IN INTERVIEWS
Binding:
A binding describes how a service wants to communicate. With binding, you can specify the
following
features:
Transport protocol
Security
Encoding format
Transaction flow
Reliability
Shape change
Transport upgrade

BasicHttpBinding:
Is the binding for the broadest interoperability,
the first-generation Web services. Transport protocols used
are HTTP or HTTPS; security is available only from the transport
protocol.

WSHttpBinding:
WSHttpBinding is the binding for the next-generation Web services,
platforms that implement SOAP extensions for security, reliability,
and transactions. The transports used are HTTP or HTTPS; for
security the WS-Security specification is implemented; transactions
are supported, as has been described, with the WS-Coordination,
WS-AtomicTransaction, and WS-BusinessActivity specifications;
reliable messaging is supported with an implementation of
WS-ReliableMessaging. WS-Profile also supports MTOM (Message
Transmission Optimization Protocol) encoding for sending
attachments. You can find specifications for the WS-* standards at
http://www.oasis-open.org.
WSDualHttpBinding:
The binding WSDualHttpBinding, in contrast to
WSHttpBinding, supports duplex messaging.

NetTcpBinding:
All standard bindings prefixed with the name Net use a binary
encoding used for communication between .NET applications.
This encoding is faster than the text encoding with WSxxx bindings.
The binding NetTcpBinding uses the TCP/IP protocol.

CustomBinding:
With a CustomBinding the transport protocol and security
requirements can be completely customized

Along with defining the binding, the service must define an endpoint. The endpoint is
dependent on the
contract, the address of the service, and the binding. In the following code sample, a
ServiceHost object
is instantiated, and the address http://localhost:8080/RoomReservation , a WsHttpBinding
instance, and the contract are added to an endpoint of the service:
static ServiceHost host;
static void StartService()
{
Uri baseAddress = new Uri(“http://localhost:8080/RoomReservation”);
host = new ServiceHost(
typeof(RoomReservationService));
WSHttpBinding binding1 = new WSHttpBinding();
host.AddServiceEndpoint(typeof(IRoomService), binding1, baseAddress);
host.Open();
}

In addition to defining the binding programmatically, you can define it with the application
configuration file. The configuration for WCF is placed inside the element
< system.serviceModel > .
The < service > element defines the services offered. Similarly, as you ’ ve seen in the
code, the service
needs an endpoint, and the endpoint contains address, binding, and contract information.
The default
binding configuration of wsHttpBinding is modified with the bindingConfiguration XML
attribute
that references the binding configuration wsHttpConfig1 . This is the binding configuration
you can
find inside the < bindings > section, which is used to change the wsHttpBinding
configuration to
enable reliableSession .
< ?xml version=”1.0” encoding=”utf-8” ? >
< configuration >
< system.serviceModel >
< services >
< service name=”Wrox.ProCSharp.WCF.RoomReservationService” >
< endpoint address=” http://localhost:8080/RoomReservation”
contract=”Wrox.ProCSharp.WCF.IRoomService”
binding=”wsHttpBinding”
bindingConfiguration=”wsHttpBinding” / >
< /service >
< /services >
< bindings >
< wsHttpBinding >
< binding name=”wsHttpBinding” >
< reliableSession enabled=”true” / >
< /binding >
< /wsHttpBinding >
< /bindings >
< /system.serviceModel >
< /configuration >

Hosting
WCF is very flexible when choosing a host to run the service. The host can be a Windows
service, a COM+ application, WAS (Windows Activation Services) or IIS, a Windows
application, or just a simple console application. When creating a custom host with Windows
Forms or WPF, you can easily create a peer - to - peer solution.

WAS Hosting
With WAS (Windows Activation Services) hosting, you get the features from the WAS
worker process
such as automatic activation of the service, health monitoring, and process recycling.
To use WAS hosting, you just need to create a Web site and a .svc file with the
ServiceHost declaration that includes the language and the name of the service
class. The code shown here is using the class Service1 . In addition, you must
specify the file that contains the service class. This class is implemented in the
same way as you saw earlier when defining a WCF service library.
<%@ServiceHost language=”C#” Service=”Service1”
CodeBehind=”Service1.svc.cs” % >
If you use a WCF service library that should be available from WAS hosting, you can create
a .svc file
that just contains a reference to the class:
< %@ ServiceHost
Service=”Wrox.ProCSharp.WCF.Services.RoomReservationService” % >
With Windows Vista and Windows Server 2008, WAS allows defining .NET TCP and Message
Queue
bindings. If you are using the previous edition, IIS 6 or IIS 5.1 that is available with
Windows Server 2003
and Windows XP, activation from a .svc file can be done only with an HTTP binding.
Clients
A client application needs a proxy to access a service. There are three ways to create a
proxy for the
client:
Visual Studio Add Service Reference — This utility creates a proxy class from the
metadata of
the service.
ServiceModel Metadata Utility tool (Svcutil.exe) — You can create a proxy class with
the
Svcutil utility. This utility reads metadata from the service to create the proxy class.
ChannelFactory class — This class is used by the proxy generated from Svcutil ; however,
it can also be used to create a proxy programmatically.
Visual Studio Add Service Reference — This utility creates a proxy class from the
metadata of the service.
Adding a service reference from Visual Studio requires accessing a WSDL document. The
WSDL document is created by a MEX endpoint that needs to be configured with the service.
With the following configuration, the endpoint with the relative address mex is using the
mexHttpBinding and implements the contract IMetadataExchange . For accessing the
metadata with an HTTP GET request, the behaviorConfiguration MexServiceBehavior is
configured.
< ?xml version=”1.0” encoding=”utf-8” ? >
< configuration >
< system.serviceModel >
< services >
< service behaviorConfiguration=” MexServiceBehavior “
name=”Wrox.ProCSharp.WCF.Services.RoomReservationService” >
< endpoint address=”Test” binding=”wsHttpBinding”
contract=”Wrox.ProCSharp.WCF.Services.IRoomService” / >
< endpoint address=”mex” binding=”mexHttpBinding”
contract=”IMetadataExchange” / >
< host >
< baseAddresses >
< add baseAddress=
“http://localhost:8731/Design_Time_Addresses/RoomReservationService/” / >
< baseAddresses >
< /host >
< /service >
< /services >
< behaviors >
< serviceBehaviors >
< behavior name=”MexServiceBehavior” >
< !-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above
before deployment -- >
< serviceMetadata httpGetEnabled=”True”/ >
< /behavior >
< /serviceBehaviors >
< /behaviors >
< /system.serviceModel >
< /configuration >

ServiceModel Metadata Utility tool (Svcutil.exe) — You can create a proxy class with
the Svcutil utility. This utility reads metadata from the service to create the proxy class.
Similar to the Add service reference from Visual Studio, the Svcutil utility needs metadata to
create the
proxy class. The Svcutil utility can create a proxy from the MEX metadata endpoint, the
metadata of
the assembly, or WSDL and XSD documentation:

svcutil http://localhost:8080/RoomReservation?wsdl /language:C# /out:proxy.cs


svcutil CourseRegistration.dll
svcutil CourseRegistration.wsdl CourseRegistration.xsd
After the proxy class is generated, it just needs to be instantiated from the client code, the
methods need
to be called, and finally the Close() method must be invoked:
RoomServiceClient client = new RoomServiceClient();
client.RegisterForCourse(roomReservation);
client.Close();
The generated proxy class derives from the base class ClientBase < TChannel > that wraps
the ChannelFactory < TChannel > class. Instead of using a generated proxy class, you can
use the
ChannelFactory < TChannel > class directly. The constructor requires the binding and
endpoint address;
next, you can create the channel and invoke methods as defined by the service contract.
Finally, the
factory must be closed:
WsHttpBinding binding = new WsHttpBinding();
EndpointAddress address =
new EndpointAddress(“http://localhost:8080/RoomService”);
ChannelFactory < IRoomService > factory =
new ChannelFactory < IStateService > (binding, address);
IRoomService channel = factory.CreateChannel();
channel.ReserveRoom(roomReservation);
//...
factory.Close();
The ChannelFactory < TChannel > class has several properties and methods, as shown in
the
following table.
Duplex Communication
For duplex communication, a contract must be specified that is implemented in the client.
Here the contract for the client is defined by the interface IMyMessageCallback . The
method implemented by the client is OnCallback() . The operation has the operation
contract setting IsOneWay=true applied.
This way, the service doesn ’ t wait until the method is successfully invoked on the client. By
default, the service instance can be invoked from only one thread (see the
ConcurrencyMode property of the service behavior that is, by default, set to
ConcurrencyMode.Single ).
If the service implementation now does a callback to the client and waits to get an answer
from the client, the thread getting the reply from the client must wait until it gets a lock to
the service object.
Because the service object is already locked by the request to the client, a deadlock occurs.
WCF detects the deadlock and throws an exception. To avoid this situation, you can change
the ConcurrencyMode
property to the value Multiple or Reentrant . With the setting Multiple , multiple threads can
access the instance concurrently. Here, you must implement locking on your own. With the
setting
Reentrant , the service instance stays single threaded, but allows answers from callback
requests to
reenter the context. Instead of changing the concurrency mode, you can specify the
IsOneWay property
with the operation contract. This way, the caller does not wait for a reply. Of course, this
setting is
possible only if return values are not expected.

The contract of the service is defined by the interface IMyMessage . The callback contract is
mapped to
the service contract with the CallbackContract property of the service contract definition:
public interface IMyMessageCallback
{
[OperationContract(IsOneWay=true)]
void OnCallback(string message);
}
[ServiceContract(CallbackContract=typeof(IMyMessageCallback))]
public interface IMyMessage
{
[OperationContract]
void MessageToServer(string message);
}
The class MessageService implements the service contract IMyMessage . The service writes
the
message from the client to the console. To access the callback contract, you can use the
OperationContext class. OperationContext.Current returns the OperationContext that is
associated with the current request from the client. With the OperationContext , you can
access session
information, message headers and properties, and, in case of a duplex communication, the
callback
channel. The generic method GetCallbackChannel() returns the channel to the client
instance.
This channel can then be used to send a message to the client by invoking the method
OnCallback()
that is defined with the callback interface IMyMessageCallback . To demonstrate that it is
also possible
to use the callback channel from the service independent of the completion of the method, a
new thread
that receives the callback channel is created. The new thread sends messages to the client
by using the
callback channel.
public class MessageService : IMyMessage
{
public void MessageToServer(string message)
{
Console.WriteLine(“message from the client: {0}”, message);
IMyMessageCallback callback =
OperationContext.Current.
GetCallbackChannel < IMyMessageCallback > ();
callback.OnCallback(“message from the server”);
new Thread(ThreadCallback).Start(callback);
}
private void ThreadCallback(object callback)
{
IMyMessageCallback messageCallback = callback as IMyMessageCallback;
for (int i = 0; i < 10; i++)
{
messageCallback.OnCallback(“message “ + i.ToString());
Thread.Sleep(1000);
}
}
}
Hosting the service is the same as it was with the previous samples, so it is not shown here.
However, for
duplex communication, you must configure a binding that supports a duplex channel. One of
the
bindings supporting a duplex channel is wsDualHttpBinding , which is configured in the
application
configuration file:
< ?xml version=”1.0” encoding=”utf-8” ? >
< configuration >
< system.serviceModel >
< services >
< service name=”Wrox.ProCSharp.WCF.MessageService” >
< endpoint contract=”Wrox.ProCSharp.WCF.IMyMessage”
binding=”wsDualHttpBinding”/ >
< host >
< baseAddresses >
< add baseAddress=”http://localhost:8731/Service1” / >
< /baseAddresses >
< /host >
< /service >
< /services >
< /system.serviceModel >
< /configuration >
With the client application, the callback contract must be implemented as shown here with
the class
ClientCallback that implements the interface IMyMessageCallback :
class ClientCallback : IMyMessageCallback
{
public void OnCallback(string message)
{
Console.WriteLine(“message from the server: {0}”, message);
}
}
With a duplex channel, you cannot use the ChannelFactory to initiate the connection to the
service as
was done previously. To create a duplex channel, you can use the DuplexChannelFactory
class. This
class has a constructor with one more parameter in addition to the binding and address
configuration.
This parameter specifies an InstanceContext that wraps one instance of the ClientCallback
class.
When passing this instance to the factory, the service can invoke the object across the
channel. The client
just needs to keep the connection open. If the connection is closed, the service cannot send
messages
across it.
WSDualHttpBinding binding = new WSDualHttpBinding();
EndpointAddress address =
new EndpointAddress(“http://localhost:8731/Service1”);
ClientCallback clientCallback = new ClientCallback();
InstanceContext context = new InstanceContext(clientCallback);
DuplexChannelFactory < IMyMessage > factory =
new DuplexChannelFactory < IMyMessage > (context, binding, address);
IMyMessage messageChannel = factory.CreateChannel();
messageChannel.MessageToServer(“From the client”);
Duplex communication is achieved by starting the service host and the client application.

Error Handling
By default, the detailed exception information that occurs in the service is not returned to
the client
application. The reason for this behavior is security. You wouldn ’ t want to give detailed
exception
information to a third party using your service. Instead, the exception should be logged on
the service
(which you can do with tracing and event logging), and an error with useful information
should be returned to the caller.
You can return SOAP faults by throwing a FaultException . Throwing a FaultException
creates an untyped SOAP fault. The preferred way of returning errors is to generate a
strongly typed SOAP fault.
The information that should be passed with a strongly typed SOAP fault is defined with a
data contract
as shown with the StateFault class:
[DataContract]
public class StateFault
{
[DataMember]
public int BadState { get; set; }
}
The type of the SOAP fault must be defined using the FaultContractAttribute with the
operation
contract:
[FaultContract(typeof(StateFault))]
[OperationContract]
void SetState(int i);
With the implementation, a FaultException < TDetail > is thrown. With the constructor you
can assign
a new TDetail object, which is a StateFault in the example. In addition, error information
within a FaultReason can be assigned to the constructor. FaultReason supports error
information in multiple
languages.
public void SetState(int i)
{
if (i == -1)
{
FaultReasonText[] text = new FaultReasonText[2];
text[0] = new FaultReasonText(“Sample Error”,
new CultureInfo(“en”));
text[1] = new FaultReasonText(“Beispiel Fehler”,
new CultureInfo(“de”));
FaultReason reason = new FaultReason(text);
throw new FaultException < StateFault > (
new StateFault() { BadState = i }, reason);
}
else
{
this.i = i;
}
}
With the client application, exceptions of type FaultException < StateFault > can be caught.
The
reason for the exception is defined by the Message property; the StateFault is accessed with
the
Detail property:
try
{
channel.SetState(-1);
}
catch (FaultException < StateFault > ex)
{
Console.WriteLine(ex.Message);
StateFault detail = ex.Detail;
Console.WriteLine(detail.BadState);
}
In addition to catching the strongly typed SOAP faults, the client application can also catch
exceptions of
the base class of FaultException < Detail > : FaultException and CommunicationException .
By
catching CommunicationException , you can also catch other exceptions related to the WCF
communication.

You might also like