Basic WCF concepts—WCF ABCs
There are many terms and concepts surrounding WCF such as address, binding, contract, endpoint, behavior, hosting, and channels. Understanding these terms is very helpful when using WCF.
Address
The WCF Address is a specific location for a service. It is the specific place to which a message will be sent. All WCF services are deployed at a specific address, listening at that address for incoming requests.
A WCF Address is normally specified as a URL, with the first part specifying the transport mechanism, and the hierarchical parts specifying the unique location of the service. For example, http://www.myweb.com/myWCFServices/SampleService is an address for a WCF service. This WCF service uses HTTP as its transport protocol, and it is located on the server www.myweb.com, with a unique service path of myWCFServices/SampleService
. The following diagram illustrates the three parts of a WCF service address.
Binding
Bindings are used to specify the transport, encoding, and protocol details required for clients and services to communicate with each other. Bindings are what WCF uses to generate the underlying wire representation of the endpoint. So, most of the details of the binding must be agreed upon by the parties that are communicating. The easiest way to achieve this is for clients of a service to use the same binding that the service uses.
A binding is made up of a collection of binding elements. Each element describes some aspect of how the service communicates with clients. A binding must include at least one transport binding element, at least one message encoding binding element (which can be provided by the transport binding element by default), and any number of other protocol binding elements. The process that builds a runtime out of this description allows each binding element to contribute code to that runtime.
WCF provides bindings that contain common selections of binding elements. These can either be used with their default settings or the default values can be modified according to user requirements. These system-provided bindings have properties that allow direct control over the binding elements and their settings.
The following are some examples of system-provided bindings:
BasicHttpBinding, WSHttpBinding, WSDualHttpBinding, WSFederationHttpBinding, NetTcpBinding, NetNamedPipeBinding, NetMsmqBinding, NetPeerTcpBinding, and MsmqIntegrationBinding.
Each one of these built-in bindings has predefined required elements for a common task, and is ready to be used in your project. For instance, the BasicHttpBinding uses HTTP as the transport for sending SOAP 1.1 messages, and it has attributes and elements such as receiveTimeout
, sendTimeout
, maxMessageSize
, and maxBufferSize
. You can use the default settings of its attributes and elements, or overwrite them as needed.
Contract
A WCF contract is a set of specifications that define the interfaces of a WCF service. A WCF service communicates with other applications according to its contracts. There are several types of WCF contracts such as Service Contract, Operation Contract, Data Contract, Message Contract, and Fault Contract.
Service contract
A service contract is the interface of the WCF service. Basically, it tells others what the service can do. It may include service-level settings such as the name of the service, the namespace of the service, and the corresponding callback contracts of the service. Inside the interface, it can define a bunch of methods, or service operations, for specific tasks. Normally, a WCF service has at least one service contract.
Operation contract
An operation contract is defined within a service contract. It defines the parameters and return type of an operation. An operation can take data of a primitive (native) data type such as an integer as a parameter, or it can take a message, which should be defined as a message contract type. Just as a service contract is an interface, an operation contract is a definition of an operation. It has to be implemented in order for the service to function as a WCF service. An operation contract also defines operation-level settings such as the transaction flow of the operation, the directions of the operation (one-way, two-way, or both ways), and the fault contract of the operation.
The following is an example of an operation contract:
[FaultContract(typeof(ProductFault))] GetProductResponse GetProduct(GetProductRequest request);
In this example, the operation contract's name is GetProduct
and it takes one input parameter, which is of the type GetProductRequest
(a message contract) and has one return value, which is of the type GetProductResponse
(another message contract). It may return a fault message, which is of the type ProductFault
(a fault contract), to the client applications. We will cover message contract and fault contract in the following sections.
Message contract
If an operation contract needs to pass a message as a parameter or return a message, the type of these messages will be defined as message contracts. A message contract defines the elements of the message as well as any message-related settings such as the level of message security, and also whether an element should go to the header or to the body.
The following is a message contract example:
namespace MyWCF.EasyNorthwind.MessageContracts { /// <summary> /// Service Contract Class - GetProductResponse /// </summary> [WCF::MessageContract(IsWrapped = false)] public partial class GetProductResponse { private MyWCF.EasyNorthwind.DataContracts.Product product; [WCF::MessageBodyMember(Name = "Product")] public MyWCF.EasyNorthwind.DataContracts.Product Product { get { return product; } set { product = value; } } } }
In this example, the namespace of the message contract is MyWCF.EasyNorthwind.MessageContracts
, and the message contract's name is GetProductResponse
. This message contract has one member, which is of the type Product
.
Data contract
Data contracts are data types of the WCF service. All data types used by the WCF service must be described in metadata to enable other applications to interoperate with the service. A data contract can be used by an operation contract as a parameter or return type, or it can be used by a message contract to define elements. If a WCF service uses only primitive (native) data types, it is not necessary to define any data contract.
The following is an example of data contract:
namespace MyWCF.EasyNorthwind.DataContracts { /// <summary> /// Data Contract Class - Product /// </summary> [WcfSerialization::DataContract(Namespace = "http://MyCompany.com/ProductService/EasyWCF/2008/05", Name = "Product")] public partial class Product { private int productID; private string productName; [WcfSerialization::DataMember(Name = "ProductID", IsRequired = false, Order = 0)] public int ProductID { get { return productID; } set { productID = value; } } [WcfSerialization::DataMember(Name = "ProductName", IsRequired = false, Order = 1)] public string ProductName { get { return productName; } set { productName = value; } } } }
In this example, the namespace of the data contract is MyWCF.EasyNorthwind.DataContracts
, the name of the data contract is Product
, and this data contract has two members (ProductID
and ProductName
).
Fault contract
In any WCF service operation contract, if an error is returned to the caller, the caller should be warned of that error. These error types are defined as fault contracts. An operation can have zero or more fault contracts associated with it.
The following is a fault contract example:
namespace MyWCF.EasyNorthwind.FaultContracts { /// <summary> /// Data Contract Class - ProductFault /// </summary> [WcfSerialization::DataContract(Namespace = "http://MyCompany.com/ProductService/EasyWCF/2008/05", Name = "ProductFault")] public partial class ProductFault { private string faultMessage; [WcfSerialization::DataMember(Name = "FaultMessage", IsRequired = false, Order = 0)] public string FaultMessage { get { return faultMessage; } set { faultMessage = value; } } } }
In this example, the namespace of the fault contract is MyWCF.EasyNorthwind.FaultContracts
, the name of the fault contract is ProductFault
, and the fault contract has only one member (FaultMessage
).
Endpoint
Messages are sent between endpoints. Endpoints are places where messages are sent or received (or both), and they define all of the information required for the message exchange. A service exposes one or more application endpoints (as well as zero or more infrastructure endpoints). A service can expose this information as the metadata that clients process to generate the appropriate WCF clients and communication stacks. When needed, the client generates an endpoint that is compatible with one of the service's endpoints.
A WCF service endpoint has an address, a binding, and a service contract (WCF ABC).
The endpoint's address is a network address where the endpoint resides. It describes, in a standard-based way, where messages should be sent. Each endpoint normally has one unique address, but sometimes two or more endpoints can share the same address.
The endpoint's binding specifies how the endpoint communicates with the world, including things such as transport protocol (TCP, HTTP), encoding (text, binary), and security requirements (SSL, SOAP message security).
The endpoint's contract specifies what the endpoint communicates, and is essentially a collection of messages organized in the operations that have basic Message Exchange Patterns (MEPs) such as one-way, duplex, or request/reply.
The following diagram shows the components of a WCF service endpoint.
Behavior
A WCF behavior is a type or settings to extend the functionality of the original type. There are many types of behaviors in WCF such as service behavior, binding behavior, contract behavior, security behavior, and channel behavior. For example, a new service behavior can be defined to specify the transaction timeout of the service, the maximum concurrent instances of the service, and whether the service publishes metadata. Behaviors are configured in the WCF service configuration file. We will configure several specific behaviors in the chapters that follow.
Hosting
A WCF service is a component that can be called by other applications. It must be hosted in an environment in order to be discovered and used by others. The WCF host is an application that controls the lifetime of the service. With .NET 3.0 and beyond, there are several ways to host the service.
Self hosting
A WCF service can be self-hosted, which means that the service runs as a standalone application and controls its own lifetime. This is the most flexible and easiest way of hosting a WCF service, but its availability and features are limited.
Windows services hosting
A WCF service can also be hosted as a Windows service. A Windows service is a process managed by the operating system and it is automatically started when Windows is started (if it is configured to do so). However, it lacks some critical features (such as versioning) for WCF services.
IIS hosting
A better way to host a WCF service is to use IIS. This is the traditional way of hosting a web service. IIS, by its nature, has many useful features such as process recycling, idle shutdown, process health monitoring, message-based activation, high availability, easy manageability, versioning, and deployment scenarios. All of these features are required for enterprise-level WCF services.
Windows Activation Services hosting
The IIS hosting method, however, comes with several limitations in the service-orientation world, the dependency on HTTP being the main culprit. With IIS hosting, many of WCF's flexible options can't be utilized. This is the reason why Microsoft specifically developed a new method called Windows Process Activation Services (WAS) to host WCF services.
WAS is the new process activation mechanism for Windows Server 2008 that is also available on Windows Vista and Windows 7. It retains the familiar IIS 6.0 process model application pools and message-based process activation and hosting features (such as rapid failure protection, health monitoring, and recycling), but it removes the dependency on HTTP from the activation architecture. IIS 7.0 uses WAS to accomplish message-based activation over HTTP. Additional WCF components also plug into WAS to provide message-based activation over the other protocols that WCF supports, such as TCP, MSMQ, and named pipes. This allows applications that use the non-HTTP communication protocols to use the IIS features such as process recycling, rapid fail protection, and the common configuration systems that were only previously available to HTTP-based applications.
This hosting option requires WAS to be properly configured, but it does not require you to write any hosting code as part of the application. (Microsoft MSN, Hosting Services, retrieved on 3/6/2008 from http://msdn2.microsoft.com/enus/library/ms730158.aspx.)
Channels
As we have seen in the previous sections, a WCF service has to be hosted in an application on the server side. On the client side, the client applications have to specify the bindings to connect to the WCF services. The binding elements are interfaces, and they have to be implemented in concrete classes. The concrete implementation of a binding element is called a channel. The binding represents the configuration and the channel is the implementation associated with that configuration. Therefore, there is a channel associated with each binding element. Channels stack on top of one another to create the concrete implementation of the binding—the channel stack.
The WCF channel stack is a layered communication stack with one or more channels that process messages. At the bottom of the stack is a transport channel that is responsible for adapting the channel stack to the underlying transport (for example, TCP, HTTP, SMTP, and other types of transport). Channels provide a low-level programming model for sending and receiving messages. This programming model relies on several interfaces and other types collectively known as the WCF channel model. The following diagram shows a simple channel stack:
Metadata
The metadata of a service describes the characteristics of the service that an external entity needs to understand in order to communicate with the service. Metadata can be consumed by the ServiceModel Metadata Utility Tool (Svcutil.exe
) to generate a WCF client and the accompanying configuration that a client application can use to interact with the service.
The metadata exposed by the service includes XML schema documents, which define the data contract of the service, and WSDL documents, which describe the methods of the service.
Though WCF services always have metadata, it is possible to hide the metadata from outsiders. If you do so, you have to pass the metadata to the client side by other means. This practice is not common but it gives your services an extra layer of security. When enabled through the configuration settings through metadata behavior, metadata for the service can be retrieved by inspecting the service and its endpoints. The following configuration setting in a WCF service configuration file will enable metadata publishing for HTTP transport protocol:
<serviceMetadata httpGetEnabled="true" />