What are contracts in WCF?
Let us explain what contracts are in WCF.
A WCF Contract is a collection of Operations that specifies what the Endpoint communicates to the outside world. Each operation is a simple message exchange, for example one-way or request/reply message exchange.
The ContractDescription class is used to describe WCF Contracts and their operations. Within a ContractDescription, each Contract operation has a corresponding OperationDescription that describes aspects of the operation such as whether the operation is one-way or request/reply. Each OperationDescription also describes the messages that make up the operation using a collection ofMessageDescriptions.
A ContractDescription is usually created from an interface or class that defines the Contract using the WCF programming model. This type is annotated with ServiceContractAttribute and its methods that correspond to Endpoint Operations are annotated with OperationContractAttribute. You can also build a ContractDescription by hand without starting with a CLR type annotated with attributes.
A duplex Contract defines two logical sets of operations: A set that the Service exposes for the Client to call and a set that the Client exposes for the Service to call. The programming model for defining a duplex Contract is to split each set in a separate type (each type must be a class or an interface) and annotate the contract that represents the service's operations with ServiceContractAttribute, referencing the contract that defines the client (or callback) operations. In addition, ContractDescription contains a reference to each of the types thereby grouping them into one duplex Contract.
Similar to Bindings, each Contract has a Name and Namespace that uniquely identify it in the Service's metadata.
Each Contract also has a collection of ContractBehaviors that are modules that modify or extend the contract's behavior
Here is a Code example of how to Define a Contract in WCF
using System.ServiceModel;
//WCF contract defined using an interface
[ServiceContract]
public interface ICalculate
{
[OperationContract]
int Add(int x, int y);
}
Here is a Code example of how to Implement a Contract in WCF
//the service class implements the WCF contract defined as an Interface
public class MathService : ICalculate
{
public int Add(int x, int y)
{ return x + y; }
}
Different types of WCF Contracts:
Service Contract
Service Contract Example
using System.ServiceModel;
[ServiceContract]
public interface ICalculate
{
[OperationContract]
double Add( double a, double b);
[OperationContract]
double Subtract( double a, double b);
}
Data Contract
Data Contract Example
[DataContract]
public class Person
{
[DataMember]
public int Id;
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
}
Resources:
What is Address Header in WCF?
Address Header in WCF Service has information which gets sent with every request. It can be used to include any processing logic or routing logic by the end point services.
WCF has the AddressHeader Class for this. This class represents a header which contains address information which can be used to identify and interact with an endpoint.
Here is an example which shows how to create address headers, access their properties, add them to a service endpoint and host the service using the endpoint:
// Create Address Header
AddressHeader addressHeaders = AddressHeader.CreateAddressHeader("MyServiceName", "http://localhost:8000/service",1);
// Associate Address Header to an Endpoint
EndpointAddress endpointAddressWithHeaders = new EndpointAddress(
new Uri("http://localhost/service1"), addressHeaders
);
Reference:
How to set the instancing mode in WCF service?
Instancing mode is set in WCF Service on the Service Level using the InstanceContextMode Enum which has these values:
1. Single--One service instance is allocated for all client calls
2. PerCall --One service instance is allocated for each client call.
3. PerSession --One service instance is allocated for each client session
Here is an example of how you can set the Instance Mode using the ServiceBehavior Attribute.
[ServiceContract]
interface IMyContract {...}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract {...}
Here is another example which sets the InstanceContextMode property of theServiceBehaviorAttribute attribute to PerCall
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
// Service class which implements the service contract.
[ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : ICalculator
{
public double Add(double n1, double n2)
{
return n1 + n2;
}
public double Subtract(double n1, double n2)
{
return n1 - n2;
}
public double Multiply(double n1, double n2)
{
return n1 * n2;
}
public double Divide(double n1, double n2)
{
return n1 / n2;
}
}
Reference:
What is the ABC of Windows Communication Foundation (WCF)?
"ABC" is the WCF mantra. "ABC" is the key to understanding how a WCF service endpoint is composed. Think Ernie, Bert, Cookie Monster or Big Bird. Remember "ABC".
- "A" stands for Address: Where is the service?
- "B" stands for Binding: How do I talk to the service?
- "C" stands for Contract: What can the service do for me?
Web services zealots who read Web Service Description Language (WSDL) descriptions at the breakfast table will easily recognize these three concepts as the three levels of abstraction expressed in WSDL. So if you live in a world full of angle brackets, you can look at it this way:
- "A" stands for Address—as expressed in the wsdl:service section and links wsdl:binding to a concrete service endpoint address.
- "B" stands for Binding—as expressed in the wsdl:binding section and binds a wsdl:portType contract description to a concrete transport, an envelope format and associated policies.
- "C" stands for Contract—as expressed in the wsdl:portType, wsdl:message and wsdl:type sections and describes types, messages, message exchange patterns and operations.
"ABC" means that writing (and configuring) a WCF service is always a three-step process:
- You define a contract and implement it on a service
- You choose or define a service binding that selects a transport along with quality of service, security and other options
- You deploy an endpoint for the contract by binding it (using the binding definition, hence the name) to a network address.
It is important to note is that these three elements are independent. A contract can support many bindings and a binding can support many contracts. A service can have many endpoints (contract bound to address) coexisting and available at the same time. So if you want to expose your service via HTTP and use SOAP 1.1 for maximum interoperability, and also want to expose it via TCP using a binary wire encoding for maximum performance, the two resulting endpoints can reside side-by-side on top of the very same service.
Of course, not all bindings necessarily satisfy the needs of a given service contract or service implementation. If a service does, for instance, absolutely depend on certain security aspects, reliable messaging, transaction flow, or other features, it can demand that any binding that is used for exposing endpoints must support them. If a binding does not support the demanded features, the WCF runtime will detect the feature mismatch and will refuse to start the service
What is a WCF Endpoint?
A WCF Service has three essential things; the Address that has info on where the Service resides, the Binding that has information on how to communicate and use the service and the Contract which defines what the service does. A combination of all this is a WCF Endpoint.
All communication with a Windows Communication Foundation (WCF) service occurs through theendpoints of the service. Endpoints provide clients access to the functionality offered by a WCF service.
Each endpoint consists of four properties:
· An address that indicates where the endpoint can be found.
· A contract that identifies the operations available.
· A set of behaviors that specify local implementation details of the endpoint
· A binding that specifies how a client can communicate with the endpoint.
Here is a sample code on how to create a WCF Service Endpoint.
[ServiceContract]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
And here is how you implement the above Service Endpoint
public class CalculatorService : ICalculator
{
public double Add(double n1, double n2)
{
return n1 + n2;
}
public double Subtract(double n1, double n2)
{
return n1 - n2;
}
public double Multiply(double n1, double n2)
{
return n1 * n2;
}
public double Divide(double n1, double n2)
{
return n1 / n2;
}
}
You can also Create a Service Endpoint using the config file. In the examples above, I showed how to create an WCF Service Endpoint using C# code, but here below you will see how to create a Service endpoint using the config file.
<configuration>
<appSettings>
<add key="baseAddress" value="http://localhost:8000/servicemodelsamples/service" />
</appSettings>
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.CalculatorService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
</baseAddresses>
</host>
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="/test"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="http://localhost:8001/hello/servicemodelsamples"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="net.tcp://localhost:9000/servicemodelsamples/service"
binding="netTcpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
References:
What is binding and how many types of bindings are there in WCF?
Windows Communication Foundation (WCF) separates how the software for an application is written from how it communicates with other software. Bindings are used to specify the transport, encoding, and protocol details required for clients and services to communicate with each other. WCF uses bindings to generate the underlying wire representation of the endpoint, so most of the binding details 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 endpoint for the service uses
The Types of WCF Bindings:
Binding Class Name
|
Transport
|
Message Encoding
|
BasicHttpBinding
|
HTTP
|
Text
|
WSHttpBinding
|
HTTP
|
Text
|
WSDualHttpBinding
|
HTTP
|
Text
|
WSFederationHttpBinding
|
HTTP
|
Text
|
NetTcpBinding
|
TCP
|
Binary
|
NetPeerTcpBinding
|
P2P
|
Binary
|
NetNamedPipesBinding
|
Named Pipes
|
Binary
|
NetMsmqBinding
|
MSMQ
|
Binary
|
MsmqIntegrationBinding
|
MSMQ
|
Not Supported (uses a pre-WCF serialization format)
|
CustomBinding
|
You Decide
|
You Decide
|
Now let us try to understand the above WCF Binding types in detail.
BasicHttpBinding
The BasicHttpBinding uses HTTP as the transport for sending SOAP 1.1 messages. A service can use this binding to expose endpoints that conform to WS-I BP 1.1, such as those that ASMX clients consume. Similarly, a client can use the BasicHttpBinding to communicate with services exposing endpoints that conform to WS-I BP 1.1, such as ASMX Web services or services configured with the BasicHttpBinding.
Security is turned off by default, but can be added setting the mode attribute of the of child element to a value other than None. It uses a "Text" message encoding and UTF-8 text encoding by default.
BasicHttpBinding Example:
<system.serviceModel>
<services>
<service
type="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
binding="basicHttpBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="Binding1"
hostNameComparisonMode="StrongWildcard"
receiveTimeout="00:10:00"
sendTimeout="00:10:00"
openTimeout="00:10:00"
closeTimeout="00:10:00"
maxReceivedMessageSize="65536"
maxBufferSize="65536"
maxBufferPoolSize="524288"
transferMode="Buffered"
messageEncoding="Text"
textEncoding="utf-8"
bypassProxyOnLocal="false"
useDefaultWebProxy="true" >
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
WSHttpBinding
The WSHttpBinding is similar to the BasicHttpBinding but provides more Web service features. It uses the HTTP transport and provides message security, as does BasicHttpBinding, but it also provides transactions, reliable messaging, and WS-Addressing, either enabled by default or available through a single control setting.
Here is an Example using WSHttpBinding
<configuration>
<system.ServiceModel>
<bindings>
<wsHttpBinding>
<binding
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="WeakWildcard"
maxReceivedMessageSize="1000"
messageEncoding="Mtom"
proxyAddress="http://foo/bar"
textEncoding="utf-16"
useDefaultWebProxy="false">
<reliableSession ordered="false"
inactivityTimeout="00:02:00"
enabled="true" />
<security mode="Transport">
<transport clientCredentialType="Digest"
proxyCredentialType="None"
realm="someRealm" />
<message clientCredentialType="Windows"
negotiateServiceCredential="false"
algorithmSuite="Aes128"
defaultProtectionLevel="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.ServiceModel>
</configuration>
WSDualHttpBinding
The WSDualHttpBinding provides the same support for Web Service protocols as theWSHttpBinding, but for use with duplex contracts. WSDualHttpBinding only supports SOAP security and requires reliable messaging. This binding requires that the client has a public URI that provides a callback endpoint for the service. This is provided by the clientBaseAddress attribute. A dual binding exposes the IP address of the client to the service. The client should use security to ensure that it only connects to services it trusts.
This binding can be used to communicate reliably through one or more SOAP intermediaries.
By default, this binding generates a runtime stack with WS-ReliableMessaging for reliability, WS-Security for message security and authentication, HTTP for message delivery, and a Text/XML message encoding
Example using WSDualHttpBinding
<configuration>
<system.ServiceModel>
<bindings>
<wsDualHttpBinding>
<binding
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
bypassProxyOnLocal="false"
clientBaseAddress="http://localhost:8001/client/"
transactionFlow="true"
hostNameComparisonMode="WeakWildcard"
maxReceivedMessageSize="1000"
messageEncoding="Mtom"
proxyAddress="http://foo/bar"
textEncoding="utf-16"
useDefaultWebProxy="false">
<reliableSession ordered="false"
inactivityTimeout="00:02:00" />
<security mode="None">
<message clientCredentialType="None"
negotiateServiceCredential="false"
algorithmSuite="Aes128" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
</system.ServiceModel>
</configuration>
WSFederationHttpBinding
Federation is the ability to share identities across multiple systems for authentication and authorization. These identities can refer to users or to machines. Federated HTTP supports SOAP security as well as mixed-mode security, but it does not support exclusively using transport security. This binding provides Windows Communication Foundation (WCF) support for the WS-Federation protocol. Services configured with this binding must use the HTTP transport.
Bindings consist of a stack of binding elements. The stack of binding elements in
wsFederationHttpBinding is the same as that contained in wsHttpBinding
The wsFederationHttpBinding controls the details of the message security settings in element of . Note that the of element provides get access only as the security used by the binding cannot be changed once the binding is created.
The wsFederationHttpBinding also provides a privactyNoticeAt attribute to set and retrieve the URI at which the privacy notice is located.
Keeping policy secure is especially important in federation scenarios. The recommendation is to use some form of security, such as HTTPS, to protect the policy from malicious users.
In federation scenarios using this binding, the service policy potentially has important information such as the key to use to encrypt the issued (SAML) token, the type of claims to put in the token, and so forth. If this policy is tampered with, an attacker could discover the key of the issued token leading to further tampering, info disclosure and other malicious behavior. To help prevent this, the policy must be obtained securely (for example using HTTPS) from the service
Example of WSFederationHttpBinding
<configuration>
<system.ServiceModel>
<bindings>
<wsFederationHttpBinding>
<binding
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="WeakWildcard"
maxReceivedMessageSize="1000"
messageEncoding="Mtom"
proxyAddress="http://foo/bar"
textEncoding="Utf16TextEncoding"
useDefaultWebProxy="false">
<reliableSession ordered="false"
inactivityTimeout="00:02:00" enabled="true" />
<security mode="None">
<message negotiateServiceCredential="false"
algorithmSuite="Aes128"
issuedTokenType="saml"
issuedKeyType="PublicKey">
<issuer address="http://localhost/Sts" />
</message>
</security>
</binding>
</wsFederationBinding>
</bindings>
</system.ServiceModel>
</configuration>
NetTcpBinding
This binding generates a run-time communication stack by default, which uses transport security, TCP for message delivery, and a binary message encoding. This binding is an appropriate Windows Communication Foundation (WCF) system-provided choice for communicating over an Intranet.
The default configuration for the netTcpBinding is faster than the configuration provided by thewsHttpBinding, but it is intended only for WCF-to-WCF communication. The security behavior is configurable using the optional securityMode attribute. The use of WS-ReliableMessaging is configurable using the optional reliableSessionEnabled attribute. But reliable messaging is off by default. More generally, the HTTP system-provided bindings such as wsHttpBinding andbasicHttpBinding are configured to turn things on by default, whereas the netTcpBinding binding turns things off by default so that you have to opt-in to get support, for example, for one of the WS-* specifications. This means that the default configuration for TCP is faster at exchanging messages between endpoints than those configured for the HTTP bindings by default.
Example of NetTcpBinding
The binding is specified in the configuration files for the client and service. The binding type is specified in the binding attribute of the element. If you want to configure the netTcpBinding binding and change some of its settings, it is necessary to define a binding configuration. The endpoint must reference the binding configuration with a bindingConfigurationattribute. In the following example, a binding configuration is defined.
<services>
<service name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
...
<endpoint address=""
binding="netTcpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
...
</service>
</services>
<bindings>
<netTcpBinding>
<binding
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
listenBacklog="10"
maxBufferPoolSize="524288"
maxBufferSize="65536"
maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32"
maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
</security>
</binding>
</netTcpBinding>
</bindings>
NetPeerTcpBinding
NetPeerTcpBinding provides support for the creation of peer-to-peer or multiparty applications using peer transport over TCP. Each peer node can host multiple peer channels defined with this binding type
Example of NetPeerTcpBinding
<configuration>
<system.ServiceModel>
<bindings>
<netPeerBinding>
<binding
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
maxBufferSize="1001"
maxConnections="123"
maxReceiveMessageSize="1000">
<reliableSession ordered="false"
inactivityTimeout="00:02:00"
enabled="true" />
<security mode="TransportWithMessageCredential">
<message clientCredentialType="CardSpace" />
</security>
</binding>
</netPeerBinding>
</bindings>
</system.ServiceModel>
</configuration>
NetNamedPipeBinding
Defines a binding that is secure, reliable, optimized for on-machine cross process communication. By default, it generates a runtime communication stack with WS-ReliableMessaging for reliability, transport security for transfer security, named pipes for message delivery, and binary message encoding
The NetNamedPipeBinding generates a run-time communication stack by default, which uses transport security, named pipes for message delivery, and a binary message encoding. This binding is an appropriate Windows Communication Foundation (WCF) system-provided choice for on-machine communication. It also supports transactions.
The default configuration for the NetNamedPipeBinding is similar to the configuration provided by the NetTcpBinding, but it is simpler because the WCF implementation is only meant for on-machine use and consequently there are fewer exposed features. The most notable difference is that the securityMode setting only offers the None and Transport options. SOAP security support is not an included option. The security behavior is configurable using the optional securityModeattribute.
Example using NetNamedPipeBinding
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
</baseAddresses>
</host>
<endpoint address="net.pipe://localhost/ServiceModelSamples/service"
binding="netNamedPipeBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netNamedPipeBinding>
<binding
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxBufferSize="65536"
maxConnections="10"
maxReceivedMessageSize="65536">
<security mode="Transport">
<transport protectionLevel="EncryptAndSign" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
NetMsmqBinding
Defines a queued binding suitable for cross-machine communication
The netMsmqBinding binding provides support for queuing by leveraging Microsoft Message Queuing (MSMQ) as a transport and enables support for loosely coupled applications, failure isolation, load leveling and disconnected operations.
<configuration>
<system.ServiceModel>
<bindings>
<netMsmqBinding>
<binding
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
deadLetterQueue="net.msmq://localhost/blah"
durable="true"
exactlyOnce="true"
maxReceivedMessageSize="1000"
maxRetries="11"
maxRetryCycles="12"
poisonMessageHandling="Disabled"
rejectAfterLastRetry="false"
retryCycleDelay="00:05:55"
timeToLive="00:11:11"
sourceJournal="true"
useMsmqTracing="true"
useActiveDirectory="true">
<security>
<message clientCredentialType="Windows" />
</security>
</netMsmqBinding>
</bindings>
</system.ServiceModel>
</configuration>
MsmqIntegrationBinding
Defines a binding that provides queuing support by routing messages through MSMQ
This binding element can be used to enable Windows Communication Foundation (WCF) applications to send messages to and receive messages from existing MSMQ applications that use either COM, MSMQ native APIs, or the types defined in the ( Default Namespace )System.Messaging namespace You can use this configuration element to specify ways to address the queue, transfer assurances, whether messages must be durably stored, and how messages should be protected and authenticated
Example using MsmqIntegrationBinding
<configuration>
<system.ServiceModel>
<bindings>
<msmqIntegrationBinding>
<binding
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
deadLetterQueue="net.msmq://localhost/blah"
durable="true"
exactlyOnce="true"
maxReceivedMessageSize="1000"
maxImmediateRetries="11"
maxRetryCycles="12"
poisonMessageHandling="Disabled"
rejectAfterLastRetry="false"
retryCycleDelay="00:05:55"
timeToLive="00:11:11"
useSourceJournal="true"
useMsmqTracing="true"
serializationFormat="Binary">
<security mode="None" />
</binding>
</msmqIntegrationBinding
</bindings>
</system.ServiceModel>
</configuration>
CustomBinding
Provides full control over the messaging stack for the user
Custom bindings provide full control over the WCF messaging stack. Special tailored bindings can be created my adding the configuration elements for specific entities. For example, the user can combine the httpsTransport section, reliableSession section and the security section to create a reliable and secure https based binding.
An individual binding defines the message stack by specifying the configuration elements for the stack elements in the order they appear on the stack. Each element defines and configures the one element of the stack. There must be one and only one transport element in each custom binding. Without this element, the messaging stack is incomplete.
The order in which elements appear in the stack matters, because it is the order in which operations are applied to the message. The recommended order of stack elements is the following:
- Transactions (optional)
- Reliable Messaging (optional)
- Security (optional)
- Transport
- Encoder (optional)
Example:
The following example shows how to create a CustomBinding object using a ReliableSessionBindingElement and an HttpTransportBindingElement
Uri baseAddress = new Uri("http://localhost:8000/servicemodelsamples/service");
// Create a ServiceHost for the CalculatorService type and provide the base address.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
// Create a custom binding that contains two binding elements.
ReliableSessionBindingElement reliableSession = new ReliableSessionBindingElement();
reliableSession.Ordered = true;
HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
httpTransport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
CustomBinding binding = new CustomBinding(reliableSession, httpTransport);
// Add an endpoint using that binding.
serviceHost.AddServiceEndpoint(typeof(ICalculator), binding, "");
// Add a MEX endpoint.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri("http://localhost:8001/servicemodelsamples");
serviceHost.Description.Behaviors.Add(smb);
// Open the ServiceHostBase to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press to terminate service." );
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
serviceHost.Close();
}
No comments:
Post a Comment